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