xml_iarchive_impl.ipp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  2. // xml_iarchive_impl.cpp:
  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 <boost/config.hpp>
  9. #include <cstring> // memcpy
  10. #include <cstddef> // NULL
  11. #if defined(BOOST_NO_STDC_NAMESPACE)
  12. namespace std{
  13. using ::memcpy;
  14. } // namespace std
  15. #endif
  16. #ifndef BOOST_NO_CWCHAR
  17. #include <cwchar> // mbstate_t and mbrtowc
  18. #if defined(BOOST_NO_STDC_NAMESPACE)
  19. namespace std{
  20. using ::mbstate_t;
  21. using ::mbrtowc;
  22. } // namespace std
  23. #endif
  24. #endif // BOOST_NO_CWCHAR
  25. #include <boost/detail/workaround.hpp> // RogueWave and Dinkumware
  26. #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
  27. #include <boost/archive/dinkumware.hpp>
  28. #endif
  29. #include <boost/core/uncaught_exceptions.hpp>
  30. #include <boost/core/no_exceptions_support.hpp>
  31. #include <boost/archive/xml_archive_exception.hpp>
  32. #include <boost/archive/iterators/dataflow_exception.hpp>
  33. #include <boost/archive/basic_xml_archive.hpp>
  34. #include <boost/archive/xml_iarchive.hpp>
  35. #include "basic_xml_grammar.hpp"
  36. namespace boost {
  37. namespace archive {
  38. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  39. // implemenations of functions specific to char archives
  40. // wide char stuff used by char archives
  41. #ifndef BOOST_NO_CWCHAR
  42. #ifndef BOOST_NO_STD_WSTRING
  43. template<class Archive>
  44. BOOST_ARCHIVE_DECL void
  45. xml_iarchive_impl<Archive>::load(std::wstring &ws){
  46. std::string s;
  47. bool result = gimpl->parse_string(is, s);
  48. if(! result)
  49. boost::serialization::throw_exception(
  50. xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
  51. );
  52. #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101))
  53. if(NULL != ws.data())
  54. #endif
  55. ws.resize(0);
  56. std::mbstate_t mbs = std::mbstate_t();
  57. const char * start = s.data();
  58. const char * end = start + s.size();
  59. while(start < end){
  60. wchar_t wc;
  61. std::size_t count = std::mbrtowc(&wc, start, end - start, &mbs);
  62. if(count == static_cast<std::size_t>(-1))
  63. boost::serialization::throw_exception(
  64. iterators::dataflow_exception(
  65. iterators::dataflow_exception::invalid_conversion
  66. )
  67. );
  68. if(count == static_cast<std::size_t>(-2))
  69. continue;
  70. start += count;
  71. ws += wc;
  72. }
  73. }
  74. #endif // BOOST_NO_STD_WSTRING
  75. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  76. template<class Archive>
  77. BOOST_ARCHIVE_DECL void
  78. xml_iarchive_impl<Archive>::load(wchar_t * ws){
  79. std::string s;
  80. bool result = gimpl->parse_string(is, s);
  81. if(! result)
  82. boost::serialization::throw_exception(
  83. xml_archive_exception(
  84. xml_archive_exception::xml_archive_parsing_error
  85. )
  86. );
  87. std::mbstate_t mbs = std::mbstate_t();
  88. const char * start = s.data();
  89. const char * end = start + s.size();
  90. while(start < end){
  91. wchar_t wc;
  92. std::size_t length = std::mbrtowc(&wc, start, end - start, &mbs);
  93. if(static_cast<std::size_t>(-1) == length)
  94. boost::serialization::throw_exception(
  95. iterators::dataflow_exception(
  96. iterators::dataflow_exception::invalid_conversion
  97. )
  98. );
  99. if(static_cast<std::size_t>(-2) == length)
  100. continue;
  101. start += length;
  102. *ws++ = wc;
  103. }
  104. *ws = L'\0';
  105. }
  106. #endif // BOOST_NO_INTRINSIC_WCHAR_T
  107. #endif // BOOST_NO_CWCHAR
  108. template<class Archive>
  109. BOOST_ARCHIVE_DECL void
  110. xml_iarchive_impl<Archive>::load(std::string &s){
  111. bool result = gimpl->parse_string(is, s);
  112. if(! result)
  113. boost::serialization::throw_exception(
  114. xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
  115. );
  116. }
  117. template<class Archive>
  118. BOOST_ARCHIVE_DECL void
  119. xml_iarchive_impl<Archive>::load(char * s){
  120. std::string tstring;
  121. bool result = gimpl->parse_string(is, tstring);
  122. if(! result)
  123. boost::serialization::throw_exception(
  124. xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
  125. );
  126. std::memcpy(s, tstring.data(), tstring.size());
  127. s[tstring.size()] = 0;
  128. }
  129. template<class Archive>
  130. BOOST_ARCHIVE_DECL void
  131. xml_iarchive_impl<Archive>::load_override(class_name_type & t){
  132. const std::string & s = gimpl->rv.class_name;
  133. if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)
  134. boost::serialization::throw_exception(
  135. archive_exception(archive_exception::invalid_class_name)
  136. );
  137. char * tptr = t;
  138. std::memcpy(tptr, s.data(), s.size());
  139. tptr[s.size()] = '\0';
  140. }
  141. template<class Archive>
  142. BOOST_ARCHIVE_DECL void
  143. xml_iarchive_impl<Archive>::init(){
  144. gimpl->init(is);
  145. this->set_library_version(
  146. library_version_type(gimpl->rv.version)
  147. );
  148. }
  149. template<class Archive>
  150. BOOST_ARCHIVE_DECL
  151. xml_iarchive_impl<Archive>::xml_iarchive_impl(
  152. std::istream &is_,
  153. unsigned int flags
  154. ) :
  155. basic_text_iprimitive<std::istream>(
  156. is_,
  157. 0 != (flags & no_codecvt)
  158. ),
  159. basic_xml_iarchive<Archive>(flags),
  160. gimpl(new xml_grammar())
  161. {
  162. if(0 == (flags & no_header))
  163. init();
  164. }
  165. template<class Archive>
  166. BOOST_ARCHIVE_DECL
  167. xml_iarchive_impl<Archive>::~xml_iarchive_impl(){
  168. if(boost::core::uncaught_exceptions() > 0)
  169. return;
  170. if(0 == (this->get_flags() & no_header)){
  171. gimpl->windup(is);
  172. }
  173. }
  174. } // namespace archive
  175. } // namespace boost