diff --git a/include/server/api/base_parameters_grammar.hpp b/include/server/api/base_parameters_grammar.hpp index b0745d824..4d441a573 100644 --- a/include/server/api/base_parameters_grammar.hpp +++ b/include/server/api/base_parameters_grammar.hpp @@ -11,8 +11,8 @@ //#define BOOST_SPIRIT_DEBUG #include -#include #include +#include namespace osrm { @@ -106,15 +106,15 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar unlimited.add("unlimited", std::numeric_limits::infinity()); - radiuses_rule = qi::lit("radiuses=") >> -(unlimited | qi::double_) % ";"; + radiuses_rule = qi::lit("radiuses=") > -(unlimited | qi::double_) % ";"; hints_rule = - qi::lit("hints=") >> + qi::lit("hints=") > qi::as_string[qi::repeat(engine::ENCODED_HINT_SIZE)[base64_char]][add_hint] % ";"; bearings_rule = - qi::lit("bearings=") >> (-(qi::short_ >> ',' >> qi::short_))[add_bearing] % ";"; - polyline_rule = qi::as_string[qi::lit("polyline(") >> +polyline_chars >> qi::lit(")")] + qi::lit("bearings=") > (-(qi::short_ > ',' > qi::short_))[add_bearing] % ";"; + polyline_rule = qi::as_string[qi::lit("polyline(") > +polyline_chars > qi::lit(")")] [polyline_to_coordinates]; - location_rule = (double_ >> qi::lit(',') >> double_)[add_coordinate]; + location_rule = (double_ > qi::lit(',') > double_)[add_coordinate]; query_rule = (location_rule % ';') | polyline_rule; base_rule = bearings_rule | radiuses_rule[set_radiuses] | hints_rule; diff --git a/include/server/api/match_parameter_grammar.hpp b/include/server/api/match_parameter_grammar.hpp index 24b693250..6671a58b6 100644 --- a/include/server/api/match_parameter_grammar.hpp +++ b/include/server/api/match_parameter_grammar.hpp @@ -47,17 +47,17 @@ struct MatchParametersGrammar final : public BaseParametersGrammar parameters.timestamps = std::move(timestamps); }; - steps_rule = qi::lit("steps=") >> qi::bool_; + steps_rule = qi::lit("steps=") > qi::bool_; geometries_rule = qi::lit("geometries=geojson")[set_geojson_type] | qi::lit("geometries=polyline")[set_polyline_type]; overview_rule = qi::lit("overview=simplified")[set_simplified_type] | qi::lit("overview=full")[set_full_type] | qi::lit("overview=false")[set_false_type]; - timestamps_rule = qi::lit("timestamps=") >> qi::uint_ % ";"; + timestamps_rule = qi::lit("timestamps=") > qi::uint_ % ";"; match_rule = steps_rule[set_steps] | geometries_rule | overview_rule | timestamps_rule[set_timestamps]; root_rule = - query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (match_rule | base_rule) % '&'); + query_rule > -qi::lit(".json") > -(qi::lit("?") > (match_rule | base_rule) % '&'); } engine::api::MatchParameters parameters; diff --git a/include/server/api/nearest_parameter_grammar.hpp b/include/server/api/nearest_parameter_grammar.hpp index 6dfe21124..09b6c2ab5 100644 --- a/include/server/api/nearest_parameter_grammar.hpp +++ b/include/server/api/nearest_parameter_grammar.hpp @@ -25,9 +25,9 @@ struct NearestParametersGrammar final : public BaseParametersGrammar const auto set_number = [this](const unsigned number) { parameters.number_of_results = number; }; - nearest_rule = (qi::lit("number=") >> qi::uint_)[set_number]; + nearest_rule = (qi::lit("number=") > qi::uint_)[set_number]; root_rule = - query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (nearest_rule | base_rule) % '&'); + query_rule > -qi::lit(".json") > -(qi::lit("?") > (nearest_rule | base_rule) % '&'); } engine::api::NearestParameters parameters; diff --git a/include/server/api/route_parameters_grammar.hpp b/include/server/api/route_parameters_grammar.hpp index c3f9803ab..4102d639e 100644 --- a/include/server/api/route_parameters_grammar.hpp +++ b/include/server/api/route_parameters_grammar.hpp @@ -49,19 +49,19 @@ struct RouteParametersGrammar : public BaseParametersGrammar }; const auto set_uturns = [this](UturnsT uturns) { parameters.uturns = std::move(uturns); }; - alternatives_rule = qi::lit("alternatives=") >> qi::bool_; - steps_rule = qi::lit("steps=") >> qi::bool_; + alternatives_rule = qi::lit("alternatives=") > qi::bool_; + steps_rule = qi::lit("steps=") > qi::bool_; geometries_rule = qi::lit("geometries=geojson")[set_geojson_type] | qi::lit("geometries=polyline")[set_polyline_type]; overview_rule = qi::lit("overview=simplified")[set_simplified_type] | qi::lit("overview=full")[set_full_type] | qi::lit("overview=false")[set_false_type]; - uturns_rule = qi::lit("uturns=default") | (qi::lit("uturns=") >> qi::bool_)[set_uturns]; + uturns_rule = qi::lit("uturns=default") | (qi::lit("uturns=") > qi::bool_)[set_uturns]; route_rule = steps_rule[set_steps] | alternatives_rule[set_alternatives] | geometries_rule | overview_rule | uturns_rule; root_rule = - query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (route_rule | base_rule) % '&'); + query_rule > -qi::lit(".json") > -(qi::lit("?") > (route_rule | base_rule) % '&'); } engine::api::RouteParameters parameters; diff --git a/include/server/api/table_parameter_grammar.hpp b/include/server/api/table_parameter_grammar.hpp index 59a212454..6d084440f 100644 --- a/include/server/api/table_parameter_grammar.hpp +++ b/include/server/api/table_parameter_grammar.hpp @@ -30,14 +30,14 @@ struct TableParametersGrammar final : public BaseParametersGrammar const auto set_sources = [this](SourcesT sources) { parameters.sources = std::move(sources); }; - destinations_rule = (qi::lit("destinations=") >> (qi::ulong_ % ";")[set_destiantions]) | + destinations_rule = (qi::lit("destinations=") > (qi::ulong_ % ";")[set_destiantions]) | qi::lit("destinations=all"); sources_rule = - (qi::lit("sources=") >> (qi::ulong_ % ";")[set_sources]) | qi::lit("sources=all"); + (qi::lit("sources=") > (qi::ulong_ % ";")[set_sources]) | qi::lit("sources=all"); table_rule = destinations_rule | sources_rule; root_rule = - query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (table_rule | base_rule) % '&'); + query_rule > -qi::lit(".json") > -(qi::lit("?") > (table_rule | base_rule) % '&'); } engine::api::TableParameters parameters; diff --git a/include/server/api/tile_parameter_grammar.hpp b/include/server/api/tile_parameter_grammar.hpp index d914a856c..ef73357b9 100644 --- a/include/server/api/tile_parameter_grammar.hpp +++ b/include/server/api/tile_parameter_grammar.hpp @@ -29,10 +29,11 @@ struct TileParametersGrammar final : boost::spirit::qi::grammar> qi::uint_[set_x] >> qi::lit(",") >> qi::uint_[set_y] >> - qi::lit(",") >> qi::uint_[set_z] >> qi::lit(")"); + query_rule = qi::lit("tile(") > qi::uint_[set_x] // + > qi::lit(",") > qi::uint_[set_y] > // + qi::lit(",") > qi::uint_[set_z] > qi::lit(")"); // - root_rule = query_rule >> qi::lit(".mvt"); + root_rule = query_rule > qi::lit(".mvt"); } engine::api::TileParameters parameters; diff --git a/include/server/api/trip_parameter_grammar.hpp b/include/server/api/trip_parameter_grammar.hpp index e3ae8b1de..52c66223a 100644 --- a/include/server/api/trip_parameter_grammar.hpp +++ b/include/server/api/trip_parameter_grammar.hpp @@ -43,7 +43,7 @@ struct TripParametersGrammar final : public BaseParametersGrammar }; const auto set_steps = [this](const StepsT steps) { parameters.steps = steps; }; - steps_rule = qi::lit("steps=") >> qi::bool_; + steps_rule = qi::lit("steps=") > qi::bool_; geometries_rule = qi::lit("geometries=geojson")[set_geojson_type] | qi::lit("geometries=polyline")[set_polyline_type]; overview_rule = qi::lit("overview=simplified")[set_simplified_type] | @@ -52,7 +52,7 @@ struct TripParametersGrammar final : public BaseParametersGrammar trip_rule = steps_rule[set_steps] | geometries_rule | overview_rule; root_rule = - query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (trip_rule | base_rule) % '&'); + query_rule > -qi::lit(".json") > -(qi::lit("?") > (trip_rule | base_rule) % '&'); } engine::api::TripParameters parameters; diff --git a/src/server/api/parameters_parser.cpp b/src/server/api/parameters_parser.cpp index 499ae1619..1d4485a03 100644 --- a/src/server/api/parameters_parser.cpp +++ b/src/server/api/parameters_parser.cpp @@ -1,11 +1,13 @@ #include "server/api/parameters_parser.hpp" +#include "server/api/match_parameter_grammar.hpp" +#include "server/api/nearest_parameter_grammar.hpp" #include "server/api/route_parameters_grammar.hpp" #include "server/api/table_parameter_grammar.hpp" -#include "server/api/nearest_parameter_grammar.hpp" -#include "server/api/trip_parameter_grammar.hpp" -#include "server/api/match_parameter_grammar.hpp" #include "server/api/tile_parameter_grammar.hpp" +#include "server/api/trip_parameter_grammar.hpp" + +#include namespace osrm { @@ -25,16 +27,29 @@ template ::value, int>::type = 0, typename std::enable_if::value, int>::type = 0> -boost::optional parseParameters(std::string::iterator &iter, const std::string::iterator end) +boost::optional parseParameters(std::string::iterator &iter, + const std::string::iterator end) { + using It = std::decay::type; + GrammarT grammar; - const auto result = boost::spirit::qi::parse(iter, end, grammar); - boost::optional parameters; - if (result && iter == end) - parameters = std::move(grammar.parameters); + try + { + const auto ok = boost::spirit::qi::parse(iter, end, grammar); - return parameters; + // return move(a.b) is needed to move b out of a and then return the rvalue by implicit move + if (ok && iter == end) + return std::move(grammar.parameters); + } + 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; } } // ns detail