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