Chris@16: /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 Chris@16: // basic_xml_oarchive.ipp: 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 // NULL Chris@16: #include Chris@16: #if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) Chris@16: namespace std{ Chris@16: using ::strlen; Chris@16: } // namespace std Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace archive { Chris@16: Chris@16: namespace detail { Chris@16: template Chris@16: struct XML_name { Chris@16: void operator()(CharType t) const{ Chris@16: const unsigned char lookup_table[] = { Chris@16: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, Chris@16: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, Chris@16: 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, // -. Chris@16: 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 0-9 Chris@16: 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // A- Chris@16: 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, // -Z _ Chris@16: 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // a- Chris@16: 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, // -z Chris@16: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, Chris@16: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Chris@16: }; Chris@16: if((unsigned)t > 127) Chris@16: return; Chris@16: if(0 == lookup_table[(unsigned)t]) Chris@16: boost::serialization::throw_exception( Chris@16: xml_archive_exception( Chris@16: xml_archive_exception::xml_archive_tag_name_error Chris@16: ) Chris@16: ); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 Chris@16: // implemenations of functions common to both types of xml output Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::write_attribute( Chris@16: const char *attribute_name, Chris@16: int t, Chris@16: const char *conjunction Chris@16: ){ Chris@16: this->This()->put(' '); Chris@16: this->This()->put(attribute_name); Chris@16: this->This()->put(conjunction); Chris@16: this->This()->save(t); Chris@16: this->This()->put('"'); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::write_attribute( Chris@16: const char *attribute_name, Chris@16: const char *key Chris@16: ){ Chris@16: this->This()->put(' '); Chris@16: this->This()->put(attribute_name); Chris@16: this->This()->put("=\""); Chris@16: this->This()->save(key); Chris@16: this->This()->put('"'); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::indent(){ Chris@16: int i; Chris@16: for(i = depth; i-- > 0;) Chris@16: this->This()->put('\t'); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_start(const char *name) Chris@16: { Chris@16: if(NULL == name) Chris@16: return; Chris@16: Chris@16: // be sure name has no invalid characters Chris@16: std::for_each(name, name + std::strlen(name), detail::XML_name()); Chris@16: Chris@16: end_preamble(); Chris@16: if(depth > 0){ Chris@16: this->This()->put('\n'); Chris@16: indent(); Chris@16: } Chris@16: ++depth; Chris@16: this->This()->put('<'); Chris@16: this->This()->save(name); Chris@16: pending_preamble = true; Chris@16: indent_next = false; Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_end(const char *name) Chris@16: { Chris@16: if(NULL == name) Chris@16: return; Chris@16: Chris@16: // be sure name has no invalid characters Chris@16: std::for_each(name, name + std::strlen(name), detail::XML_name()); Chris@16: Chris@16: end_preamble(); Chris@16: --depth; Chris@16: if(indent_next){ Chris@16: this->This()->put('\n'); Chris@16: indent(); Chris@16: } Chris@16: indent_next = true; Chris@16: this->This()->put("This()->save(name); Chris@16: this->This()->put('>'); Chris@16: if(0 == depth) Chris@16: this->This()->put('\n'); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::end_preamble(){ Chris@16: if(pending_preamble){ Chris@16: this->This()->put('>'); Chris@16: pending_preamble = false; Chris@16: } Chris@16: } Chris@16: #if 0 Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override(const object_id_type & t, int) Chris@16: { Chris@16: int i = t.t; // extra .t is for borland Chris@16: write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); Chris@16: } Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override( Chris@16: const object_reference_type & t, Chris@16: int Chris@16: ){ Chris@16: int i = t.t; // extra .t is for borland Chris@16: write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); Chris@16: } Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override(const version_type & t, int) Chris@16: { Chris@16: int i = t.t; // extra .t is for borland Chris@16: write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); Chris@16: } Chris@16: #endif Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override(const object_id_type & t, int) Chris@16: { Chris@16: // borland doesn't do conversion of STRONG_TYPEDEFs very well Chris@16: const unsigned int i = t; Chris@16: write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); Chris@16: } Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override( Chris@16: const object_reference_type & t, Chris@16: int Chris@16: ){ Chris@16: const unsigned int i = t; Chris@16: write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); Chris@16: } Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override(const version_type & t, int) Chris@16: { Chris@16: const unsigned int i = t; Chris@16: write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override(const class_id_type & t, int) Chris@16: { Chris@16: write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); Chris@16: } Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override( Chris@16: const class_id_reference_type & t, Chris@16: int Chris@16: ){ Chris@16: write_attribute(BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(), t); Chris@16: } Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override( Chris@16: const class_id_optional_type & t, Chris@16: int Chris@16: ){ Chris@16: write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); Chris@16: } Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override(const class_name_type & t, int) Chris@16: { Chris@16: const char * key = t; Chris@16: if(NULL == key) Chris@16: return; Chris@16: write_attribute(BOOST_ARCHIVE_XML_CLASS_NAME(), key); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::save_override(const tracking_type & t, int) Chris@16: { Chris@16: write_attribute(BOOST_ARCHIVE_XML_TRACKING(), t.t); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: basic_xml_oarchive::init(){ Chris@16: // xml header Chris@16: this->This()->put("\n"); Chris@16: this->This()->put("\n"); Chris@16: // xml document wrapper - outer root Chris@16: this->This()->put("This()->put(">\n"); Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) Chris@16: basic_xml_oarchive::basic_xml_oarchive(unsigned int flags) : Chris@16: detail::common_oarchive(flags), Chris@16: depth(0), Chris@16: indent_next(false), Chris@16: pending_preamble(false) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) Chris@16: basic_xml_oarchive::~basic_xml_oarchive(){ Chris@16: if(0 == (this->get_flags() & no_header)){ Chris@16: BOOST_TRY{ Chris@16: this->This()->put("\n"); Chris@16: } Chris@16: BOOST_CATCH(...){} Chris@16: BOOST_CATCH_END Chris@16: } Chris@16: } Chris@16: Chris@16: } // namespace archive Chris@16: } // namespace boost