basic_xml_oarchive.ipp 7.5 KB

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