File indexing completed on 2025-01-30 09:33:00
0001 #ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP
0002 #define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP
0003
0004
0005 #if defined(_MSC_VER)
0006 # pragma once
0007 #endif
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <boost/config.hpp>
0020 #include <boost/detail/workaround.hpp>
0021 #include <boost/assert.hpp>
0022
0023 #include <boost/serialization/throw_exception.hpp>
0024
0025 #include <boost/archive/iterators/unescape.hpp>
0026 #include <boost/archive/iterators/dataflow_exception.hpp>
0027
0028 namespace boost {
0029 namespace archive {
0030 namespace iterators {
0031
0032
0033
0034 template<class Base>
0035 class xml_unescape
0036 : public unescape<xml_unescape<Base>, Base>
0037 {
0038 friend class boost::iterator_core_access;
0039 typedef xml_unescape<Base> this_t;
0040 typedef unescape<this_t, Base> super_t;
0041 typedef typename boost::iterator_reference<this_t> reference_type;
0042
0043 reference_type dereference() const {
0044 return unescape<xml_unescape<Base>, Base>::dereference();
0045 }
0046 public:
0047
0048 #if BOOST_WORKAROUND(BOOST_MSVC, < 1900)
0049 typedef int value_type;
0050 #else
0051 typedef typename super_t::value_type value_type;
0052 #endif
0053
0054 void drain_residue(const char *literal);
0055 value_type drain();
0056
0057 template<class T>
0058 xml_unescape(T start) :
0059 super_t(Base(static_cast< T >(start)))
0060 {}
0061
0062 xml_unescape(const xml_unescape & rhs) :
0063 super_t(rhs.base_reference())
0064 {}
0065 };
0066
0067 template<class Base>
0068 void xml_unescape<Base>::drain_residue(const char * literal){
0069 do{
0070 if(* literal != * ++(this->base_reference()))
0071 boost::serialization::throw_exception(
0072 dataflow_exception(
0073 dataflow_exception::invalid_xml_escape_sequence
0074 )
0075 );
0076 }
0077 while('\0' != * ++literal);
0078 }
0079
0080
0081
0082
0083
0084 template<class Base>
0085 typename xml_unescape<Base>::value_type
0086
0087 xml_unescape<Base>::drain(){
0088 value_type retval = * this->base_reference();
0089 if('&' != retval){
0090 return retval;
0091 }
0092 retval = * ++(this->base_reference());
0093 switch(retval){
0094 case 'l':
0095 drain_residue("t;");
0096 retval = '<';
0097 break;
0098 case 'g':
0099 drain_residue("t;");
0100 retval = '>';
0101 break;
0102 case 'a':
0103 retval = * ++(this->base_reference());
0104 switch(retval){
0105 case 'p':
0106 drain_residue("os;");
0107 retval = '\'';
0108 break;
0109 case 'm':
0110 drain_residue("p;");
0111 retval = '&';
0112 break;
0113 }
0114 break;
0115 case 'q':
0116 drain_residue("uot;");
0117 retval = '"';
0118 break;
0119 }
0120 return retval;
0121 }
0122
0123 }
0124 }
0125 }
0126
0127 #endif