1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 2// basic_xml_oarchive.ipp: 3 4// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 5// Distributed under the Boost Software License, Version 1.0. (See 6// accompanying file LICENSE_1_0.txt or copy at 7// http://www.boost.org/LICENSE_1_0.txt) 8 9// See http://www.boost.org for updates, documentation, and revision history. 10 11#include <algorithm> 12#include <cstddef> // NULL 13#include <cstring> 14#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) 15namespace std{ 16 using ::strlen; 17} // namespace std 18#endif 19 20#include <boost/archive/basic_xml_archive.hpp> 21#include <boost/archive/basic_xml_oarchive.hpp> 22#include <boost/archive/xml_archive_exception.hpp> 23#include <boost/core/no_exceptions_support.hpp> 24 25namespace boost { 26namespace archive { 27 28namespace detail { 29template<class CharType> 30struct XML_name { 31 void operator()(CharType t) const{ 32 const unsigned char lookup_table[] = { 33 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 34 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 35 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, // -. 36 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 0-9 37 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // A- 38 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, // -Z _ 39 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // a- 40 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, // -z 41 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 42 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 43 }; 44 if((unsigned)t > 127) 45 return; 46 if(0 == lookup_table[(unsigned)t]) 47 boost::serialization::throw_exception( 48 xml_archive_exception( 49 xml_archive_exception::xml_archive_tag_name_error 50 ) 51 ); 52 } 53}; 54 55} // namespace detail 56 57/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 58// implemenations of functions common to both types of xml output 59 60template<class Archive> 61BOOST_ARCHIVE_OR_WARCHIVE_DECL void 62basic_xml_oarchive<Archive>::write_attribute( 63 const char *attribute_name, 64 int t, 65 const char *conjunction 66){ 67 this->This()->put(' '); 68 this->This()->put(attribute_name); 69 this->This()->put(conjunction); 70 this->This()->save(t); 71 this->This()->put('"'); 72} 73 74template<class Archive> 75BOOST_ARCHIVE_OR_WARCHIVE_DECL void 76basic_xml_oarchive<Archive>::write_attribute( 77 const char *attribute_name, 78 const char *key 79){ 80 this->This()->put(' '); 81 this->This()->put(attribute_name); 82 this->This()->put("=\""); 83 this->This()->save(key); 84 this->This()->put('"'); 85} 86 87template<class Archive> 88BOOST_ARCHIVE_OR_WARCHIVE_DECL void 89basic_xml_oarchive<Archive>::indent(){ 90 int i; 91 for(i = depth; i-- > 0;) 92 this->This()->put('\t'); 93} 94 95template<class Archive> 96BOOST_ARCHIVE_OR_WARCHIVE_DECL void 97basic_xml_oarchive<Archive>::save_start(const char *name) 98{ 99 if(NULL == name) 100 return; 101 102 // be sure name has no invalid characters 103 std::for_each(name, name + std::strlen(name), detail::XML_name<const char>()); 104 105 end_preamble(); 106 if(depth > 0){ 107 this->This()->put('\n'); 108 indent(); 109 } 110 ++depth; 111 this->This()->put('<'); 112 this->This()->save(name); 113 pending_preamble = true; 114 indent_next = false; 115} 116 117template<class Archive> 118BOOST_ARCHIVE_OR_WARCHIVE_DECL void 119basic_xml_oarchive<Archive>::save_end(const char *name) 120{ 121 if(NULL == name) 122 return; 123 124 // be sure name has no invalid characters 125 std::for_each(name, name + std::strlen(name), detail::XML_name<const char>()); 126 127 end_preamble(); 128 --depth; 129 if(indent_next){ 130 this->This()->put('\n'); 131 indent(); 132 } 133 indent_next = true; 134 this->This()->put("</"); 135 this->This()->save(name); 136 this->This()->put('>'); 137 if(0 == depth) 138 this->This()->put('\n'); 139} 140 141template<class Archive> 142BOOST_ARCHIVE_OR_WARCHIVE_DECL void 143basic_xml_oarchive<Archive>::end_preamble(){ 144 if(pending_preamble){ 145 this->This()->put('>'); 146 pending_preamble = false; 147 } 148} 149#if 0 150template<class Archive> 151BOOST_ARCHIVE_OR_WARCHIVE_DECL void 152basic_xml_oarchive<Archive>::save_override(const object_id_type & t) 153{ 154 int i = t.t; // extra .t is for borland 155 write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); 156} 157template<class Archive> 158BOOST_ARCHIVE_OR_WARCHIVE_DECL void 159basic_xml_oarchive<Archive>::save_override( 160 const object_reference_type & t, 161 int 162){ 163 int i = t.t; // extra .t is for borland 164 write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); 165} 166template<class Archive> 167BOOST_ARCHIVE_OR_WARCHIVE_DECL void 168basic_xml_oarchive<Archive>::save_override(const version_type & t) 169{ 170 int i = t.t; // extra .t is for borland 171 write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); 172} 173#endif 174 175template<class Archive> 176BOOST_ARCHIVE_OR_WARCHIVE_DECL void 177basic_xml_oarchive<Archive>::save_override(const object_id_type & t) 178{ 179 // borland doesn't do conversion of STRONG_TYPEDEFs very well 180 const unsigned int i = t; 181 write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); 182} 183template<class Archive> 184BOOST_ARCHIVE_OR_WARCHIVE_DECL void 185basic_xml_oarchive<Archive>::save_override( 186 const object_reference_type & t 187){ 188 const unsigned int i = t; 189 write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); 190} 191template<class Archive> 192BOOST_ARCHIVE_OR_WARCHIVE_DECL void 193basic_xml_oarchive<Archive>::save_override(const version_type & t) 194{ 195 const unsigned int i = t; 196 write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); 197} 198 199template<class Archive> 200BOOST_ARCHIVE_OR_WARCHIVE_DECL void 201basic_xml_oarchive<Archive>::save_override(const class_id_type & t) 202{ 203 write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); 204} 205template<class Archive> 206BOOST_ARCHIVE_OR_WARCHIVE_DECL void 207basic_xml_oarchive<Archive>::save_override( 208 const class_id_reference_type & t 209){ 210 write_attribute(BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(), t); 211} 212template<class Archive> 213BOOST_ARCHIVE_OR_WARCHIVE_DECL void 214basic_xml_oarchive<Archive>::save_override( 215 const class_id_optional_type & t 216){ 217 write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); 218} 219template<class Archive> 220BOOST_ARCHIVE_OR_WARCHIVE_DECL void 221basic_xml_oarchive<Archive>::save_override(const class_name_type & t) 222{ 223 const char * key = t; 224 if(NULL == key) 225 return; 226 write_attribute(BOOST_ARCHIVE_XML_CLASS_NAME(), key); 227} 228 229template<class Archive> 230BOOST_ARCHIVE_OR_WARCHIVE_DECL void 231basic_xml_oarchive<Archive>::save_override(const tracking_type & t) 232{ 233 write_attribute(BOOST_ARCHIVE_XML_TRACKING(), t.t); 234} 235 236template<class Archive> 237BOOST_ARCHIVE_OR_WARCHIVE_DECL void 238basic_xml_oarchive<Archive>::init(){ 239 // xml header 240 this->This()->put("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n"); 241 this->This()->put("<!DOCTYPE boost_serialization>\n"); 242 // xml document wrapper - outer root 243 this->This()->put("<boost_serialization"); 244 write_attribute("signature", BOOST_ARCHIVE_SIGNATURE()); 245 write_attribute("version", BOOST_ARCHIVE_VERSION()); 246 this->This()->put(">\n"); 247} 248 249template<class Archive> 250BOOST_ARCHIVE_OR_WARCHIVE_DECL void 251basic_xml_oarchive<Archive>::windup(){ 252 // xml_trailer 253 this->This()->put("</boost_serialization>\n"); 254} 255 256template<class Archive> 257BOOST_ARCHIVE_OR_WARCHIVE_DECL 258basic_xml_oarchive<Archive>::basic_xml_oarchive(unsigned int flags) : 259 detail::common_oarchive<Archive>(flags), 260 depth(0), 261 pending_preamble(false), 262 indent_next(false) 263{ 264} 265 266template<class Archive> 267BOOST_ARCHIVE_OR_WARCHIVE_DECL 268basic_xml_oarchive<Archive>::~basic_xml_oarchive(){ 269} 270 271} // namespace archive 272} // namespace boost 273