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