xml_wiarchive_impl.ipp 5.1 KB

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