1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 2// xml_woarchive_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#include <boost/config.hpp> 10#ifndef BOOST_NO_STD_WSTREAMBUF 11 12#include <ostream> 13#include <string> 14#include <algorithm> // std::copy 15#include <locale> 16 17#include <cstring> // strlen 18#include <cstdlib> // mbtowc 19#ifndef BOOST_NO_CWCHAR 20#include <cwchar> // wcslen 21#endif 22 23#include <boost/config.hpp> 24#if defined(BOOST_NO_STDC_NAMESPACE) 25namespace std{ 26 using ::strlen; 27 #if ! defined(BOOST_NO_INTRINSIC_WCHAR_T) 28 using ::mbtowc; 29 using ::wcslen; 30 #endif 31} // namespace std 32#endif 33 34#include <boost/core/uncaught_exceptions.hpp> 35 36#include <boost/archive/xml_woarchive.hpp> 37#include <boost/archive/detail/utf8_codecvt_facet.hpp> 38 39#include <boost/serialization/throw_exception.hpp> 40 41#include <boost/archive/iterators/xml_escape.hpp> 42#include <boost/archive/iterators/wchar_from_mb.hpp> 43#include <boost/archive/iterators/ostream_iterator.hpp> 44#include <boost/archive/iterators/dataflow_exception.hpp> 45 46namespace boost { 47namespace archive { 48 49/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 50// implemenations of functions specific to wide char archives 51 52// copy chars to output escaping to xml and widening characters as we go 53template<class InputIterator> 54void save_iterator(std::wostream &os, InputIterator begin, InputIterator end){ 55 typedef iterators::wchar_from_mb< 56 iterators::xml_escape<InputIterator> 57 > xmbtows; 58 std::copy( 59 xmbtows(begin), 60 xmbtows(end), 61 boost::archive::iterators::ostream_iterator<wchar_t>(os) 62 ); 63} 64 65template<class Archive> 66BOOST_WARCHIVE_DECL void 67xml_woarchive_impl<Archive>::save(const std::string & s){ 68 // note: we don't use s.begin() and s.end() because dinkumware 69 // doesn't have string::value_type defined. So use a wrapper 70 // around these values to implement the definitions. 71 const char * begin = s.data(); 72 const char * end = begin + s.size(); 73 save_iterator(os, begin, end); 74} 75 76#ifndef BOOST_NO_STD_WSTRING 77template<class Archive> 78BOOST_WARCHIVE_DECL void 79xml_woarchive_impl<Archive>::save(const std::wstring & ws){ 80#if 0 81 typedef iterators::xml_escape<std::wstring::const_iterator> xmbtows; 82 std::copy( 83 xmbtows(ws.begin()), 84 xmbtows(ws.end()), 85 boost::archive::iterators::ostream_iterator<wchar_t>(os) 86 ); 87#endif 88 typedef iterators::xml_escape<const wchar_t *> xmbtows; 89 std::copy( 90 xmbtows(ws.data()), 91 xmbtows(ws.data() + ws.size()), 92 boost::archive::iterators::ostream_iterator<wchar_t>(os) 93 ); 94} 95#endif //BOOST_NO_STD_WSTRING 96 97template<class Archive> 98BOOST_WARCHIVE_DECL void 99xml_woarchive_impl<Archive>::save(const char * s){ 100 save_iterator(os, s, s + std::strlen(s)); 101} 102 103#ifndef BOOST_NO_INTRINSIC_WCHAR_T 104template<class Archive> 105BOOST_WARCHIVE_DECL void 106xml_woarchive_impl<Archive>::save(const wchar_t * ws){ 107 typedef iterators::xml_escape<const wchar_t *> xmbtows; 108 std::copy( 109 xmbtows(ws), 110 xmbtows(ws + std::wcslen(ws)), 111 boost::archive::iterators::ostream_iterator<wchar_t>(os) 112 ); 113} 114#endif 115 116template<class Archive> 117BOOST_WARCHIVE_DECL 118xml_woarchive_impl<Archive>::xml_woarchive_impl( 119 std::wostream & os_, 120 unsigned int flags 121) : 122 basic_text_oprimitive<std::wostream>( 123 os_, 124 true // don't change the codecvt - use the one below 125 ), 126 basic_xml_oarchive<Archive>(flags) 127{ 128 if(0 == (flags & no_codecvt)){ 129 archive_locale = std::locale( 130 os_.getloc(), 131 new boost::archive::detail::utf8_codecvt_facet 132 ); 133 os_.flush(); 134 os_.imbue(archive_locale); 135 } 136} 137 138template<class Archive> 139BOOST_WARCHIVE_DECL 140xml_woarchive_impl<Archive>::~xml_woarchive_impl(){ 141 if(boost::core::uncaught_exceptions() > 0) 142 return; 143 if(0 == (this->get_flags() & no_header)){ 144 os << L"</boost_serialization>"; 145 } 146} 147 148template<class Archive> 149BOOST_WARCHIVE_DECL void 150xml_woarchive_impl<Archive>::save_binary( 151 const void *address, 152 std::size_t count 153){ 154 this->end_preamble(); 155 #if ! defined(__MWERKS__) 156 this->basic_text_oprimitive<std::wostream>::save_binary( 157 #else 158 this->basic_text_oprimitive::save_binary( 159 #endif 160 address, 161 count 162 ); 163 this->indent_next = true; 164} 165 166} // namespace archive 167} // namespace boost 168 169#endif //BOOST_NO_STD_WSTREAMBUF 170