source: NonGTP/Boost/boost/archive/impl/basic_xml_oarchive.ipp @ 857

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