/srv/osrm/osrm-backend/src/server/api
Edit: /srv/osrm/osrm-backend/src/server/api/url_parser.cpp (2975B)
#include "server/api/url_parser.hpp"
#include "engine/polyline_compressor.hpp"
#include
#include
#include
#include
#include
#include
BOOST_FUSION_ADAPT_STRUCT(osrm::server::api::ParsedURL,
(std::string, service)(unsigned, version)(std::string,
profile)(std::string, query))
// Keep impl. TU local
namespace
{
namespace ph = boost::phoenix;
namespace qi = boost::spirit::qi;
template //
struct URLParser final : qi::grammar
{
URLParser() : URLParser::base_type(start)
{
using boost::spirit::repository::qi::iter_pos;
identifier = qi::char_("a-zA-Z0-9_.~:-");
percent_encoding =
qi::char_('%') > qi::uint_parser()[qi::_val = qi::_1];
polyline_chars = qi::char_("a-zA-Z0-9_[]{}@?|\\~`^") | percent_encoding;
all_chars = polyline_chars | qi::char_("=,;:&().-");
service = +identifier;
version = qi::uint_;
profile = +identifier;
query = +all_chars;
// Example input: /route/v1/driving/7.416351,43.731205;7.420363,43.736189
start = qi::lit('/') > service > qi::lit('/') > qi::lit('v') > version > qi::lit('/') >
profile > qi::lit('/') >
qi::omit[iter_pos[ph::bind(&osrm::server::api::ParsedURL::prefix_length, qi::_val) =
qi::_1 - qi::_r1]] > query;
BOOST_SPIRIT_DEBUG_NODES((start)(service)(version)(profile)(query))
}
qi::rule start;
qi::rule service;
qi::rule version;
qi::rule profile;
qi::rule query;
qi::rule identifier;
qi::rule all_chars;
qi::rule polyline_chars;
qi::rule percent_encoding;
};
} // namespace
namespace osrm::server::api
{
boost::optional parseURL(std::string::iterator &iter, const std::string::iterator end)
{
using It = std::decay::type;
static URLParser const parser;
ParsedURL out;
try
{
const auto ok = boost::spirit::qi::parse(iter, end, parser(boost::phoenix::val(iter)), out);
if (ok && iter == end)
return boost::make_optional(out);
}
catch (const qi::expectation_failure &failure)
{
// The grammar above using expectation parsers ">" does not automatically increment the
// iterator to the failing position. Extract the position from the exception ourselves.
iter = failure.first;
}
return boost::none;
}
} // namespace osrm::server::api