]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP |
2 | #define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP | |
3 | ||
4 | // MS compatible compilers support #pragma once | |
5 | #if defined(_MSC_VER) | |
6 | # pragma once | |
7 | #endif | |
8 | ||
9 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 | |
10 | // xml_unescape.hpp | |
11 | ||
12 | // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . | |
13 | // Use, modification and distribution is subject to the Boost Software | |
14 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
15 | // http://www.boost.org/LICENSE_1_0.txt) | |
16 | ||
17 | // See http://www.boost.org for updates, documentation, and revision history. | |
18 | ||
19 | #include <boost/assert.hpp> | |
20 | ||
21 | #include <boost/serialization/throw_exception.hpp> | |
22 | ||
23 | #include <boost/archive/iterators/unescape.hpp> | |
24 | #include <boost/archive/iterators/dataflow_exception.hpp> | |
25 | ||
26 | namespace boost { | |
27 | namespace archive { | |
28 | namespace iterators { | |
29 | ||
30 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 | |
31 | // replace &??? xml escape sequences with the corresponding characters | |
32 | template<class Base> | |
33 | class xml_unescape | |
34 | : public unescape<xml_unescape<Base>, Base> | |
35 | { | |
36 | friend class boost::iterator_core_access; | |
37 | typedef xml_unescape<Base> this_t; | |
38 | typedef unescape<this_t, Base> super_t; | |
39 | typedef typename boost::iterator_reference<this_t> reference_type; | |
40 | ||
41 | reference_type dereference() const { | |
42 | return unescape<xml_unescape<Base>, Base>::dereference(); | |
43 | } | |
44 | public: | |
45 | // workaround msvc 7.1 ICU crash | |
46 | #if defined(BOOST_MSVC) | |
47 | typedef int value_type; | |
48 | #else | |
49 | typedef typename this_t::value_type value_type; | |
50 | #endif | |
51 | ||
52 | void drain_residue(const char *literal); | |
53 | value_type drain(); | |
54 | ||
55 | template<class T> | |
56 | xml_unescape(T start) : | |
57 | super_t(Base(static_cast< T >(start))) | |
58 | {} | |
59 | // intel 7.1 doesn't like default copy constructor | |
60 | xml_unescape(const xml_unescape & rhs) : | |
61 | super_t(rhs.base_reference()) | |
62 | {} | |
63 | }; | |
64 | ||
65 | template<class Base> | |
66 | void xml_unescape<Base>::drain_residue(const char * literal){ | |
67 | do{ | |
68 | if(* literal != * ++(this->base_reference())) | |
69 | boost::serialization::throw_exception( | |
70 | dataflow_exception( | |
71 | dataflow_exception::invalid_xml_escape_sequence | |
72 | ) | |
73 | ); | |
74 | } | |
75 | while('\0' != * ++literal); | |
76 | } | |
77 | ||
78 | // note key constraint on this function is that can't "look ahead" any | |
79 | // more than necessary into base iterator. Doing so would alter the base | |
80 | // iterator refenence which would make subsequent iterator comparisons | |
81 | // incorrect and thereby break the composiblity of iterators. | |
82 | template<class Base> | |
83 | typename xml_unescape<Base>::value_type | |
84 | //int | |
85 | xml_unescape<Base>::drain(){ | |
86 | value_type retval = * this->base_reference(); | |
87 | if('&' != retval){ | |
88 | return retval; | |
89 | } | |
90 | retval = * ++(this->base_reference()); | |
91 | switch(retval){ | |
92 | case 'l': // < | |
93 | drain_residue("t;"); | |
94 | retval = '<'; | |
95 | break; | |
96 | case 'g': // > | |
97 | drain_residue("t;"); | |
98 | retval = '>'; | |
99 | break; | |
100 | case 'a': | |
101 | retval = * ++(this->base_reference()); | |
102 | switch(retval){ | |
103 | case 'p': // ' | |
104 | drain_residue("os;"); | |
105 | retval = '\''; | |
106 | break; | |
107 | case 'm': // & | |
108 | drain_residue("p;"); | |
109 | retval = '&'; | |
110 | break; | |
111 | } | |
112 | break; | |
113 | case 'q': | |
114 | drain_residue("uot;"); | |
115 | retval = '"'; | |
116 | break; | |
117 | } | |
118 | return retval; | |
119 | } | |
120 | ||
121 | } // namespace iterators | |
122 | } // namespace archive | |
123 | } // namespace boost | |
124 | ||
125 | #endif // BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP |