#include <string>
#include <strstream>
#include <boost/spirit.hpp>
#include <iobind/xml_escape_policy.hpp>
#include <iobind/parser_utils.hpp>
namespace iobind{
namespace details{
const chset_p escapes_reserved_p("$&+'/:;=?@");
struct unescapes_reserved : boost::spirit::symbols<char>
{
unescapes_reserved()
{
add
("36" , '$')
("38" , '&')
("43" , '+')
("44" , '\'')
("57" , '/')
("48" , ':')
("59" , ';')
("61" , '=')
("63" , '?')
("64" , '@')
;
}
} unescapes_reserved_p;
const chset_p escapes_unsafe_p(" \"<>#%{}|\\^~[]`");
struct unescapes_unsafe : boost::spirit::symbols<char>
{
unescapes_unsafe()
{
add
("36" , ' ')
("38" , '\"')
("43" , '<')
("44" , '>')
("57" , '#')
("48" , '%')
("59" , '{')
("61" , '}')
("63" , '|')
("64" , '\\')
("64" , '^')
("64" , '~')
("64" , '[')
("64" , ']')
("64" , '`')
;
}
} unescapes_unsafe_p;
struct unescape_from_url_grammar : boost::spirit::grammar<unescape_from_url_grammar>
{
std::ostream& out;
explicit unescape_from_url_grammar( std::ostream& out_)
:out(out_){};
template <typename ScannerT>
struct definition
{
definition(unescape_from_url_grammar const& self)
{
using namespace boost::spirit;
// the rest is ok
encoded_string=
*(
unescapes_p[concat_symbol(self.out)]
| anychar_p[concat_string(self.out)]
);
};
boost::spirit::rule<ScannerT> encoded_string;
boost::spirit::rule<ScannerT> const& start() const { return encoded_string; };
};
};
struct escape_to_xml_grammar : boost::spirit::grammar<escape_to_xml_grammar>
{
std::ostream& out;
explicit escape_to_xml_grammar( std::ostream& out_)
:out(out_){};
template <typename ScannerT>
struct definition
{
definition(escape_to_xml_grammar const& self)
{
using namespace boost::spirit;
// the rest is ok
encoded_string=
*(
escapes_p[concat_symbol(self.out)]
| anychar_p[concat_string(self.out)]
);
};
boost::spirit::rule<ScannerT> encoded_string;
boost::spirit::rule<ScannerT> const& start() const { return encoded_string; };
};
};
}; //details
std::string escape_string_to_xml( std::string const& str)
{
using namespace boost::spirit;
std::ostringstream out;
parse_info<> info = boost::spirit::parse(
str.c_str(),
details::escape_to_xml_grammar(out)
);
out<<std::ends;
return out.str();
};
std::string unescape_string_from_xml( std::string const& str)
{
using namespace boost::spirit;
std::ostringstream out;
parse_info<> info = boost::spirit::parse(
str.c_str(),
details::unescape_from_xml_grammar(out)
);
out<<std::ends;
return out.str();
};
};