File indexing completed on 2025-01-18 09:28:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <boost/config.hpp>
0012 #include <cstring> // memcpy
0013 #include <cstddef> // NULL
0014
0015 #if defined(BOOST_NO_STDC_NAMESPACE)
0016 namespace std{
0017 using ::memcpy;
0018 }
0019 #endif
0020
0021 #ifndef BOOST_NO_CWCHAR
0022 #include <cwchar> // mbstate_t and mbrtowc
0023 #if defined(BOOST_NO_STDC_NAMESPACE)
0024 namespace std{
0025 using ::mbstate_t;
0026 using ::mbrtowc;
0027 }
0028 #endif
0029 #endif
0030
0031 #include <boost/detail/workaround.hpp> // RogueWave and Dinkumware
0032 #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
0033 #include <boost/archive/dinkumware.hpp>
0034 #endif
0035
0036 #include <boost/core/uncaught_exceptions.hpp>
0037 #include <boost/core/no_exceptions_support.hpp>
0038
0039 #include <boost/archive/xml_archive_exception.hpp>
0040 #include <boost/archive/iterators/dataflow_exception.hpp>
0041 #include <boost/archive/basic_xml_archive.hpp>
0042 #include <boost/archive/xml_iarchive.hpp>
0043
0044 #include "basic_xml_grammar.hpp"
0045
0046 namespace boost {
0047 namespace archive {
0048
0049
0050
0051
0052
0053
0054 #ifndef BOOST_NO_CWCHAR
0055 #ifndef BOOST_NO_STD_WSTRING
0056 template<class Archive>
0057 BOOST_ARCHIVE_DECL void
0058 xml_iarchive_impl<Archive>::load(std::wstring &ws){
0059 std::string s;
0060 bool result = gimpl->parse_string(is, s);
0061 if(! result)
0062 boost::serialization::throw_exception(
0063 xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
0064 );
0065
0066 #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101))
0067 if(NULL != ws.data())
0068 #endif
0069 ws.resize(0);
0070 std::mbstate_t mbs = std::mbstate_t();
0071 const char * start = s.data();
0072 const char * end = start + s.size();
0073 while(start < end){
0074 wchar_t wc;
0075 std::size_t count = std::mbrtowc(&wc, start, end - start, &mbs);
0076 if(count == static_cast<std::size_t>(-1))
0077 boost::serialization::throw_exception(
0078 iterators::dataflow_exception(
0079 iterators::dataflow_exception::invalid_conversion
0080 )
0081 );
0082 if(count == static_cast<std::size_t>(-2))
0083 continue;
0084 start += count;
0085 ws += wc;
0086 }
0087 }
0088 #endif
0089
0090 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
0091 template<class Archive>
0092 BOOST_ARCHIVE_DECL void
0093 xml_iarchive_impl<Archive>::load(wchar_t * ws){
0094 std::string s;
0095 bool result = gimpl->parse_string(is, s);
0096 if(! result)
0097 boost::serialization::throw_exception(
0098 xml_archive_exception(
0099 xml_archive_exception::xml_archive_parsing_error
0100 )
0101 );
0102
0103 std::mbstate_t mbs = std::mbstate_t();
0104 const char * start = s.data();
0105 const char * end = start + s.size();
0106 while(start < end){
0107 wchar_t wc;
0108 std::size_t length = std::mbrtowc(&wc, start, end - start, &mbs);
0109 if(static_cast<std::size_t>(-1) == length)
0110 boost::serialization::throw_exception(
0111 iterators::dataflow_exception(
0112 iterators::dataflow_exception::invalid_conversion
0113 )
0114 );
0115 if(static_cast<std::size_t>(-2) == length)
0116 continue;
0117
0118 start += length;
0119 *ws++ = wc;
0120 }
0121 *ws = L'\0';
0122 }
0123 #endif
0124
0125 #endif
0126
0127 template<class Archive>
0128 BOOST_ARCHIVE_DECL void
0129 xml_iarchive_impl<Archive>::load(std::string &s){
0130 bool result = gimpl->parse_string(is, s);
0131 if(! result)
0132 boost::serialization::throw_exception(
0133 xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
0134 );
0135 }
0136
0137 template<class Archive>
0138 BOOST_ARCHIVE_DECL void
0139 xml_iarchive_impl<Archive>::load(char * s){
0140 std::string tstring;
0141 bool result = gimpl->parse_string(is, tstring);
0142 if(! result)
0143 boost::serialization::throw_exception(
0144 xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
0145 );
0146 std::memcpy(s, tstring.data(), tstring.size());
0147 s[tstring.size()] = 0;
0148 }
0149
0150 template<class Archive>
0151 BOOST_ARCHIVE_DECL void
0152 xml_iarchive_impl<Archive>::load_override(class_name_type & t){
0153 const std::string & s = gimpl->rv.class_name;
0154 if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)
0155 boost::serialization::throw_exception(
0156 archive_exception(archive_exception::invalid_class_name)
0157 );
0158 char * tptr = t;
0159 std::memcpy(tptr, s.data(), s.size());
0160 tptr[s.size()] = '\0';
0161 }
0162
0163 template<class Archive>
0164 BOOST_ARCHIVE_DECL void
0165 xml_iarchive_impl<Archive>::init(){
0166 gimpl->init(is);
0167 this->set_library_version(
0168 boost::serialization::library_version_type(gimpl->rv.version)
0169 );
0170 }
0171
0172 template<class Archive>
0173 BOOST_ARCHIVE_DECL
0174 xml_iarchive_impl<Archive>::xml_iarchive_impl(
0175 std::istream &is_,
0176 unsigned int flags
0177 ) :
0178 basic_text_iprimitive<std::istream>(
0179 is_,
0180 0 != (flags & no_codecvt)
0181 ),
0182 basic_xml_iarchive<Archive>(flags),
0183 gimpl(new xml_grammar())
0184 {}
0185
0186 template<class Archive>
0187 BOOST_ARCHIVE_DECL
0188 xml_iarchive_impl<Archive>::~xml_iarchive_impl(){
0189 if(boost::core::uncaught_exceptions() > 0)
0190 return;
0191 if(0 == (this->get_flags() & no_header)){
0192 gimpl->windup(is);
0193 }
0194 }
0195 }
0196 }