]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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__) | |
15 | namespace 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 | ||
25 | namespace boost { | |
26 | namespace archive { | |
27 | ||
28 | namespace detail { | |
29 | template<class CharType> | |
30 | struct 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 | ||
60 | template<class Archive> | |
61 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
62 | basic_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 | ||
74 | template<class Archive> | |
75 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
76 | basic_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 | ||
87 | template<class Archive> | |
88 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
89 | basic_xml_oarchive<Archive>::indent(){ | |
90 | int i; | |
91 | for(i = depth; i-- > 0;) | |
92 | this->This()->put('\t'); | |
93 | } | |
94 | ||
95 | template<class Archive> | |
96 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
97 | basic_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 | ||
117 | template<class Archive> | |
118 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
119 | basic_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 | ||
141 | template<class Archive> | |
142 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
143 | basic_xml_oarchive<Archive>::end_preamble(){ | |
144 | if(pending_preamble){ | |
145 | this->This()->put('>'); | |
146 | pending_preamble = false; | |
147 | } | |
148 | } | |
149 | #if 0 | |
150 | template<class Archive> | |
151 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
152 | basic_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 | } | |
157 | template<class Archive> | |
158 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
159 | basic_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 | } | |
166 | template<class Archive> | |
167 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
168 | basic_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 | ||
175 | template<class Archive> | |
176 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
177 | basic_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 | } | |
183 | template<class Archive> | |
184 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
185 | basic_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 | } | |
191 | template<class Archive> | |
192 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
193 | basic_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 | ||
199 | template<class Archive> | |
200 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
201 | basic_xml_oarchive<Archive>::save_override(const class_id_type & t) | |
202 | { | |
203 | write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); | |
204 | } | |
205 | template<class Archive> | |
206 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
207 | basic_xml_oarchive<Archive>::save_override( | |
208 | const class_id_reference_type & t | |
209 | ){ | |
210 | write_attribute(BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(), t); | |
211 | } | |
212 | template<class Archive> | |
213 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
214 | basic_xml_oarchive<Archive>::save_override( | |
215 | const class_id_optional_type & t | |
216 | ){ | |
217 | write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); | |
218 | } | |
219 | template<class Archive> | |
220 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
221 | basic_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 | ||
229 | template<class Archive> | |
230 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
231 | basic_xml_oarchive<Archive>::save_override(const tracking_type & t) | |
232 | { | |
233 | write_attribute(BOOST_ARCHIVE_XML_TRACKING(), t.t); | |
234 | } | |
235 | ||
236 | template<class Archive> | |
237 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
238 | basic_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 | ||
249 | template<class Archive> | |
250 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
251 | basic_xml_oarchive<Archive>::windup(){ | |
252 | // xml_trailer | |
253 | this->This()->put("</boost_serialization>\n"); | |
254 | } | |
255 | ||
256 | template<class Archive> | |
257 | BOOST_ARCHIVE_OR_WARCHIVE_DECL | |
258 | basic_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 | ||
266 | template<class Archive> | |
267 | BOOST_ARCHIVE_OR_WARCHIVE_DECL | |
268 | basic_xml_oarchive<Archive>::~basic_xml_oarchive(){ | |
269 | } | |
270 | ||
271 | } // namespace archive | |
272 | } // namespace boost |