Chris@16: /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 Chris@16: // xml_iarchive_impl.cpp: Chris@16: Chris@16: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org for updates, documentation, and revision history. Chris@16: Chris@16: #include Chris@16: #include // memcpy Chris@16: #include // NULL Chris@16: #if defined(BOOST_NO_STDC_NAMESPACE) Chris@16: namespace std{ Chris@16: using ::memcpy; Chris@16: } // namespace std Chris@16: #endif Chris@16: Chris@16: #ifndef BOOST_NO_CWCHAR Chris@16: #include // mbtowc Chris@16: #if defined(BOOST_NO_STDC_NAMESPACE) Chris@16: namespace std{ Chris@16: using ::mbtowc; Chris@16: } // namespace std Chris@16: #endif Chris@16: #endif // BOOST_NO_CWCHAR Chris@16: Chris@16: #include // RogueWave and Dinkumware Chris@16: #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) Chris@16: #include Chris@16: #endif Chris@16: Chris@101: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include "basic_xml_grammar.hpp" Chris@16: Chris@16: namespace boost { Chris@16: namespace archive { Chris@16: Chris@16: /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 Chris@16: // implemenations of functions specific to char archives Chris@16: Chris@16: // wide char stuff used by char archives Chris@16: Chris@16: #ifndef BOOST_NO_CWCHAR Chris@16: #ifndef BOOST_NO_STD_WSTRING Chris@16: template Chris@16: BOOST_ARCHIVE_DECL(void) Chris@16: xml_iarchive_impl::load(std::wstring &ws){ Chris@16: std::string s; Chris@16: bool result = gimpl->parse_string(is, s); Chris@16: if(! result) Chris@16: boost::serialization::throw_exception( Chris@16: xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) Chris@16: ); Chris@16: Chris@16: #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) Chris@16: if(NULL != ws.data()) Chris@16: #endif Chris@16: ws.resize(0); Chris@16: const char * start = s.data(); Chris@16: const char * end = start + s.size(); Chris@16: while(start < end){ Chris@16: wchar_t wc; Chris@16: int resultx = std::mbtowc(&wc, start, end - start); Chris@16: if(0 < resultx){ Chris@16: start += resultx; Chris@16: ws += wc; Chris@16: continue; Chris@16: } Chris@16: boost::serialization::throw_exception( Chris@16: iterators::dataflow_exception( Chris@16: iterators::dataflow_exception::invalid_conversion Chris@16: ) Chris@16: ); Chris@16: } Chris@16: } Chris@16: #endif // BOOST_NO_STD_WSTRING Chris@16: Chris@16: #ifndef BOOST_NO_INTRINSIC_WCHAR_T Chris@16: template Chris@16: BOOST_ARCHIVE_DECL(void) Chris@16: xml_iarchive_impl::load(wchar_t * ws){ Chris@16: std::string s; Chris@16: bool result = gimpl->parse_string(is, s); Chris@16: if(! result) Chris@16: boost::serialization::throw_exception( Chris@16: xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) Chris@16: ); Chris@16: Chris@16: const char * start = s.data(); Chris@16: const char * end = start + s.size(); Chris@16: while(start < end){ Chris@16: wchar_t wc; Chris@101: int length = std::mbtowc(&wc, start, end - start); Chris@101: if(0 < length){ Chris@101: start += length; Chris@16: *ws++ = wc; Chris@16: continue; Chris@16: } Chris@16: boost::serialization::throw_exception( Chris@16: iterators::dataflow_exception( Chris@16: iterators::dataflow_exception::invalid_conversion Chris@16: ) Chris@16: ); Chris@16: } Chris@16: *ws = L'\0'; Chris@16: } Chris@16: #endif // BOOST_NO_INTRINSIC_WCHAR_T Chris@16: Chris@16: #endif // BOOST_NO_CWCHAR Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_DECL(void) Chris@16: xml_iarchive_impl::load(std::string &s){ Chris@16: bool result = gimpl->parse_string(is, s); Chris@16: if(! result) Chris@16: boost::serialization::throw_exception( Chris@16: xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) Chris@16: ); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_DECL(void) Chris@16: xml_iarchive_impl::load(char * s){ Chris@16: std::string tstring; Chris@16: bool result = gimpl->parse_string(is, tstring); Chris@16: if(! result) Chris@16: boost::serialization::throw_exception( Chris@16: xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) Chris@16: ); Chris@16: std::memcpy(s, tstring.data(), tstring.size()); Chris@16: s[tstring.size()] = 0; Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_DECL(void) Chris@16: xml_iarchive_impl::load_override(class_name_type & t, int){ Chris@16: const std::string & s = gimpl->rv.class_name; Chris@16: if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) Chris@16: boost::serialization::throw_exception( Chris@16: archive_exception(archive_exception::invalid_class_name) Chris@16: ); Chris@16: char * tptr = t; Chris@16: std::memcpy(tptr, s.data(), s.size()); Chris@16: tptr[s.size()] = '\0'; Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_DECL(void) Chris@16: xml_iarchive_impl::init(){ Chris@16: gimpl->init(is); Chris@16: this->set_library_version( Chris@16: library_version_type(gimpl->rv.version) Chris@16: ); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) Chris@16: xml_iarchive_impl::xml_iarchive_impl( Chris@16: std::istream &is_, Chris@16: unsigned int flags Chris@16: ) : Chris@16: basic_text_iprimitive( Chris@16: is_, Chris@16: 0 != (flags & no_codecvt) Chris@16: ), Chris@16: basic_xml_iarchive(flags), Chris@16: gimpl(new xml_grammar()) Chris@16: { Chris@101: if(0 == (flags & no_header)) Chris@101: init(); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) Chris@16: xml_iarchive_impl::~xml_iarchive_impl(){ Chris@16: if(0 == (this->get_flags() & no_header)){ Chris@16: BOOST_TRY{ Chris@16: gimpl->windup(is); Chris@16: } Chris@16: BOOST_CATCH(...){} Chris@16: BOOST_CATCH_END Chris@16: } Chris@16: } Chris@16: } // namespace archive Chris@16: } // namespace boost