00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <string>
00020 #include <sstream>
00021 #include <boost/format.hpp>
00022 #include <boost/spirit.hpp>
00023 #include "parser_utils.hpp"
00024 #include "xml_escape_parser.hpp"
00025
00026
00027 namespace iobind{
00028 namespace parser{
00029 namespace detail{
00030
00031 struct escapes : boost::spirit::symbols<std::string>
00032 {
00033 escapes()
00034 {
00035 add
00036 ("<" , "lt")
00037 (">" , "gt")
00038 ("&" , "amp")
00039 ("'" , "apos")
00040 ("\"" , "quot")
00041 ;
00042 }
00043
00044 } escapes_p;
00045
00046 struct unescapes : boost::spirit::symbols<std::string>
00047 {
00048 unescapes()
00049 {
00050 add
00051 ("lt", "<")
00052 ("gt",">")
00053 ("amp","&")
00054 ("apos","\'")
00055 ("quot","\"")
00056 ;
00057 }
00058 } unescapes_p;
00059
00060 struct unescape_from_xml_grammar : boost::spirit::grammar<unescape_from_xml_grammar>
00061 {
00062 std::ostream& out;
00063
00064 explicit unescape_from_xml_grammar( std::ostream& out_)
00065 :out(out_){};
00066
00067 template <typename ScannerT>
00068 struct definition
00069 {
00070 definition(unescape_from_xml_grammar const& self)
00071 {
00072 using namespace boost::spirit;
00073
00074 begin = ch_p('&');
00075 end = ch_p(';');
00076
00077 encoded_string=
00078 *(
00079 begin >> unescapes_p[concat_symbol(self.out)] >> end
00080 | anychar_p[concat_string(self.out)]
00081 );
00082 };
00083
00084 boost::spirit::rule<ScannerT> encoded_string, begin, end;
00085 boost::spirit::rule<ScannerT> const& start() const { return encoded_string; };
00086 };
00087 };
00088
00089 struct escape_to_xml_grammar : boost::spirit::grammar<escape_to_xml_grammar>
00090 {
00091 std::ostream& out;
00092
00093 explicit escape_to_xml_grammar( std::ostream& out_)
00094 :out(out_){};
00095
00096 template <typename ScannerT>
00097 struct definition
00098 {
00099 definition(escape_to_xml_grammar const& self)
00100 {
00101 using namespace boost::spirit;
00102 concat_pre_post_symbol concatener(self.out, "&", ";");
00103
00104
00105 encoded_string=
00106 *(
00107 escapes_p[concatener]
00108 | anychar_p[concat_string(self.out)]
00109 );
00110 };
00111
00112 boost::spirit::rule<ScannerT> encoded_string;
00113 boost::spirit::rule<ScannerT> const& start() const { return encoded_string; };
00114 };
00115 };
00116
00117 };
00118
00119
00120 std::string xml_escape_parser::escape( std::string const& str) const
00121 {
00122 using namespace boost::spirit;
00123
00124 std::ostringstream out;
00125
00126 parse_info<> info = boost::spirit::parse(
00127 str.c_str(),
00128 detail::escape_to_xml_grammar(out)
00129 );
00130
00131 return out.str();
00132 };
00133
00134 std::string xml_escape_parser::unescape( std::string const& str) const
00135 {
00136 using namespace boost::spirit;
00137
00138 std::ostringstream out;
00139
00140 parse_info<> info = boost::spirit::parse(
00141 str.c_str(),
00142 detail::unescape_from_xml_grammar(out)
00143 );
00144
00145 return out.str();
00146 };
00147 };
00148 };
00149