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

Revision 857, 5.4 KB checked in by igarcia, 18 years ago (diff)
Line 
1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// xml_iarchive_impl.cpp:
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 <boost/config.hpp>
12#include <cstring> // memcpy
13#if defined(BOOST_NO_STDC_NAMESPACE)
14namespace std{
15    using ::memcpy;
16} // namespace std
17#endif
18
19#ifndef BOOST_NO_CWCHAR
20#include <cstdlib> // mbtowc
21#if defined(BOOST_NO_STDC_NAMESPACE)
22namespace std{
23    using ::mbtowc;
24 } // namespace std
25#endif
26#endif // BOOST_NO_CWCHAR
27
28#include <boost/detail/workaround.hpp> // RogueWave and Dinkumware
29#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
30#include <boost/archive/dinkumware.hpp>
31#endif
32
33#include <boost/detail/no_exceptions_support.hpp>
34
35#include <boost/archive/archive_exception.hpp>
36#include <boost/archive/iterators/dataflow_exception.hpp>
37#include <boost/archive/basic_xml_archive.hpp>
38#include <boost/archive/xml_iarchive.hpp>
39
40#include "basic_xml_grammar.hpp"
41
42namespace boost {
43namespace archive {
44
45/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
46// implemenations of functions specific to char archives
47
48// wide char stuff used by char archives
49
50#ifndef BOOST_NO_CWCHAR
51#ifndef BOOST_NO_STD_WSTRING
52template<class Archive>
53BOOST_ARCHIVE_DECL(void)
54xml_iarchive_impl<Archive>::load(std::wstring &ws){
55    std::string s;
56    bool result = gimpl->parse_string(is, s);
57    if(! result)
58        boost::throw_exception(
59            xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
60        );
61   
62    #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101))
63    if(NULL != ws.data())
64    #endif
65        ws.resize(0);
66    const char * start = s.data();
67    const char * end = start + s.size();
68    while(start < end){
69        wchar_t wc;
70        int result = std::mbtowc(&wc, start, end - start);
71        if(0 < result){
72            start += result;
73            ws += wc;
74            continue;
75        }
76        boost::throw_exception(
77            iterators::dataflow_exception(
78                iterators::dataflow_exception::invalid_conversion
79            )
80        );
81    }
82}
83#endif // BOOST_NO_STD_WSTRING
84
85#ifndef BOOST_NO_INTRINSIC_WCHAR_T
86template<class Archive>
87BOOST_ARCHIVE_DECL(void)
88xml_iarchive_impl<Archive>::load(wchar_t * ws){
89    std::string s;
90    bool result = gimpl->parse_string(is, s);
91    if(! result)
92        boost::throw_exception(
93            xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
94        );
95       
96    const char * start = s.data();
97    const char * end = start + s.size();
98    while(start < end){
99        wchar_t wc;
100        int result = std::mbtowc(&wc, start, end - start);
101        if(0 < result){
102            start += result;
103            *ws++ = wc;
104            continue;
105        }
106        boost::throw_exception(
107            iterators::dataflow_exception(
108                iterators::dataflow_exception::invalid_conversion
109            )
110        );
111    }
112    *ws = L'\0';
113}
114#endif
115
116#endif // BOOST_NO_CWCHAR
117
118template<class Archive>
119BOOST_ARCHIVE_DECL(void)
120xml_iarchive_impl<Archive>::load(std::string &s){
121    bool result = gimpl->parse_string(is, s);
122    if(! result)
123        boost::throw_exception(
124            xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
125        );
126}
127
128template<class Archive>
129BOOST_ARCHIVE_DECL(void)
130xml_iarchive_impl<Archive>::load(char * s){
131    std::string tstring;
132    bool result = gimpl->parse_string(is, tstring);
133    if(! result)
134        boost::throw_exception(
135            xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
136        );
137    std::memcpy(s, tstring.data(), tstring.size());
138    s[tstring.size()] = 0;
139}
140
141template<class Archive>
142BOOST_ARCHIVE_DECL(void)
143xml_iarchive_impl<Archive>::load_override(class_name_type & t, int){
144    const std::string & s = gimpl->rv.class_name;
145    if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)
146        boost::throw_exception(archive_exception::invalid_class_name);
147    char * tptr = t;
148    std::memcpy(tptr, s.data(), s.size());
149    tptr[s.size()] = '\0';
150}
151
152template<class Archive>
153BOOST_ARCHIVE_DECL(void)
154xml_iarchive_impl<Archive>::init(){
155    gimpl->init(is);
156}
157
158template<class Archive>
159BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
160xml_iarchive_impl<Archive>::xml_iarchive_impl(
161    std::istream &is_,
162    unsigned int flags
163) :
164    basic_text_iprimitive<std::istream>(
165        is_,
166        0 != (flags & no_codecvt)
167    ),
168    basic_xml_iarchive<Archive>(flags),
169    gimpl(new xml_grammar())
170{
171    if(0 == (flags & no_header)){
172        BOOST_TRY{
173            init();
174        }
175        BOOST_CATCH(...){
176            delete gimpl;
177            #ifndef BOOST_NO_EXCEPTIONS
178                throw; // re-throw
179            #endif
180        }
181        BOOST_CATCH_END
182    }
183}
184
185template<class Archive>
186BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
187xml_iarchive_impl<Archive>::~xml_iarchive_impl(){
188    if(0 == (this->get_flags() & no_header)){
189        BOOST_TRY{
190            gimpl->windup(is);
191        }
192        BOOST_CATCH(...){}
193        BOOST_CATCH_END
194    }
195    delete gimpl;
196}
197} // namespace archive
198} // namespace boost
Note: See TracBrowser for help on using the repository browser.