diff --git a/benchmark/test_expression_parse.cpp b/benchmark/test_expression_parse.cpp index eb93fd433..4c911f821 100644 --- a/benchmark/test_expression_parse.cpp +++ b/benchmark/test_expression_parse.cpp @@ -39,8 +39,7 @@ public: expr_("((([mapnik::geometry_type]=2) and ([oneway]=1)) and ([class]='path'))") {} bool validate() const { - mapnik::transcoder tr("utf-8"); - mapnik::expression_grammar expr_grammar(tr); + mapnik::expression_grammar expr_grammar;; mapnik::expression_ptr expr = mapnik::parse_expression(expr_,expr_grammar); std::string result = mapnik::to_expression_string(*expr); bool ret = (result == expr_); @@ -52,8 +51,7 @@ public: } void operator()() const { - mapnik::transcoder tr("utf-8"); - mapnik::expression_grammar expr_grammar(tr); + mapnik::expression_grammar expr_grammar; for (std::size_t i=0;i #include #include -#include -#include -#include #if defined(HAVE_CAIRO) #include @@ -58,9 +55,6 @@ int main ( int argc , char** argv) datasource_cache::instance().register_datasources("plugins/input/"); freetype_engine::register_font("fonts/dejavu-fonts-ttf-2.33/ttf/DejaVuSans.ttf"); - mapnik::transcoder tr("utf-8"); - mapnik::expression_grammar expr_grammar(tr); - Map m(800,600); m.set_background(parse_color("white")); m.set_srs(srs_merc); @@ -70,7 +64,7 @@ int main ( int argc , char** argv) feature_type_style provpoly_style; { rule r; - r.set_filter(parse_expression("[NAME_EN] = 'Ontario'", expr_grammar)); + r.set_filter(parse_expression("[NAME_EN] = 'Ontario'")); { polygon_symbolizer poly_sym; put(poly_sym, keys::fill, color(250, 190, 183)); @@ -80,7 +74,7 @@ int main ( int argc , char** argv) } { rule r; - r.set_filter(parse_expression("[NOM_FR] = 'Québec'", expr_grammar)); + r.set_filter(parse_expression("[NOM_FR] = 'Québec'")); { polygon_symbolizer poly_sym; put(poly_sym, keys::fill, color(217, 235, 203)); @@ -113,7 +107,7 @@ int main ( int argc , char** argv) feature_type_style qcdrain_style; { rule r; - r.set_filter(parse_expression("[HYC] = 8", expr_grammar)); + r.set_filter(parse_expression("[HYC] = 8")); { polygon_symbolizer poly_sym; put(poly_sym, keys::fill, color(153, 204, 255)); @@ -127,7 +121,7 @@ int main ( int argc , char** argv) feature_type_style roads34_style; { rule r; - r.set_filter(parse_expression("[CLASS] = 3 or [CLASS] = 4", expr_grammar)); + r.set_filter(parse_expression("[CLASS] = 3 or [CLASS] = 4")); { line_symbolizer line_sym; put(line_sym,keys::stroke,color(171,158,137)); @@ -144,7 +138,7 @@ int main ( int argc , char** argv) feature_type_style roads2_style_1; { rule r; - r.set_filter(parse_expression("[CLASS] = 2", expr_grammar)); + r.set_filter(parse_expression("[CLASS] = 2")); { line_symbolizer line_sym; put(line_sym,keys::stroke,color(171,158,137)); @@ -160,7 +154,7 @@ int main ( int argc , char** argv) feature_type_style roads2_style_2; { rule r; - r.set_filter(parse_expression("[CLASS] = 2", expr_grammar)); + r.set_filter(parse_expression("[CLASS] = 2")); { line_symbolizer line_sym; put(line_sym,keys::stroke,color(255,250,115)); @@ -177,7 +171,7 @@ int main ( int argc , char** argv) feature_type_style roads1_style_1; { rule r; - r.set_filter(parse_expression("[CLASS] = 1", expr_grammar)); + r.set_filter(parse_expression("[CLASS] = 1")); { line_symbolizer line_sym; put(line_sym,keys::stroke,color(188,149,28)); @@ -193,7 +187,7 @@ int main ( int argc , char** argv) feature_type_style roads1_style_2; { rule r; - r.set_filter(parse_expression("[CLASS] = 1", expr_grammar)); + r.set_filter(parse_expression("[CLASS] = 1")); { line_symbolizer line_sym; put(line_sym,keys::stroke,color(242,191,36)); @@ -218,7 +212,7 @@ int main ( int argc , char** argv) placement_finder->defaults.format->fill = color(0,0,0); placement_finder->defaults.format->halo_fill = color(255,255,200); placement_finder->defaults.format->halo_radius = 1; - placement_finder->defaults.set_old_style_expression(parse_expression("[GEONAME]", expr_grammar)); + placement_finder->defaults.set_old_style_expression(parse_expression("[GEONAME]")); put(text_sym, keys::text_placements_, placement_finder); r.append(std::move(text_sym)); } diff --git a/include/mapnik/expression_grammar.hpp b/include/mapnik/expression_grammar.hpp index 6674f2129..85fce2e5d 100644 --- a/include/mapnik/expression_grammar.hpp +++ b/include/mapnik/expression_grammar.hpp @@ -127,10 +127,11 @@ struct expression_grammar : qi::grammar { typedef qi::rule rule_type; - explicit expression_grammar(mapnik::transcoder const& tr); + explicit expression_grammar(); qi::real_parser > strict_double; typename integer_parser::type int__; + mapnik::transcoder tr_; boost::phoenix::function unicode_; boost::phoenix::function regex_match_; boost::phoenix::function regex_replace_; diff --git a/include/mapnik/expression_grammar_impl.hpp b/include/mapnik/expression_grammar_impl.hpp index 39891d0a1..a46f444cf 100644 --- a/include/mapnik/expression_grammar_impl.hpp +++ b/include/mapnik/expression_grammar_impl.hpp @@ -64,11 +64,12 @@ expr_node regex_replace_impl::operator() (T0 & node, T1 const& pattern, T2 const } template -expression_grammar::expression_grammar(mapnik::transcoder const& tr) +expression_grammar::expression_grammar() : expression_grammar::base_type(expr), - unicode_(unicode_impl(tr)), - regex_match_(regex_match_impl(tr)), - regex_replace_(regex_replace_impl(tr)) + tr_("utf-8"), + unicode_(unicode_impl(tr_)), + regex_match_(regex_match_impl(tr_)), + regex_replace_(regex_replace_impl(tr_)) { qi::_1_type _1; qi::_a_type _a; diff --git a/include/mapnik/parse_transform.hpp b/include/mapnik/parse_transform.hpp index 2a98b213d..8e9edebf7 100644 --- a/include/mapnik/parse_transform.hpp +++ b/include/mapnik/parse_transform.hpp @@ -39,6 +39,9 @@ MAPNIK_DECL transform_list_ptr parse_transform(std::string const& str); MAPNIK_DECL transform_list_ptr parse_transform(std::string const& str, std::string const& encoding); +MAPNIK_DECL bool parse_transform(transform_list& list, + std::string const& str); + MAPNIK_DECL bool parse_transform(transform_list& list, std::string const& str, transform_expression_grammar_string const& g); diff --git a/include/mapnik/transform_expression_grammar.hpp b/include/mapnik/transform_expression_grammar.hpp index 886ffaa1f..fda73f7f0 100644 --- a/include/mapnik/transform_expression_grammar.hpp +++ b/include/mapnik/transform_expression_grammar.hpp @@ -38,7 +38,7 @@ namespace mapnik { struct transform_expression_grammar : qi::grammar { - explicit transform_expression_grammar(expression_grammar const& g); + explicit transform_expression_grammar(); typedef qi::rule node_rule; typedef qi::rule list_rule; @@ -57,6 +57,7 @@ namespace mapnik { qi::rule rotate; qi::rule skewX; qi::rule skewY; + mapnik::expression_grammar g_; }; } // namespace mapnik diff --git a/include/mapnik/xml_attribute_cast.hpp b/include/mapnik/xml_attribute_cast.hpp index d5d527972..227456195 100644 --- a/include/mapnik/xml_attribute_cast.hpp +++ b/include/mapnik/xml_attribute_cast.hpp @@ -160,7 +160,7 @@ struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const& tree, std::string const& source) { - return parse_color(source, tree.color_grammar); + return parse_color(source); } }; @@ -187,7 +187,7 @@ struct do_xml_attribute_cast } else { - mapnik::expression_ptr expr = parse_expression(source, tree.expr_grammar); + mapnik::expression_ptr expr = parse_expression(source); tree.expr_cache_.insert(std::move(std::make_pair(source,expr))); return expr; } diff --git a/include/mapnik/xml_tree.hpp b/include/mapnik/xml_tree.hpp index 77c7034a6..29a1f02cb 100644 --- a/include/mapnik/xml_tree.hpp +++ b/include/mapnik/xml_tree.hpp @@ -26,20 +26,15 @@ // mapnik #include #include -#include -#include -#include -#include -#include -#include #include //stl #include - +#include namespace mapnik { + class xml_tree { public: @@ -54,11 +49,6 @@ private: transcoder tr_; public: mutable std::map expr_cache_; - mapnik::css_color_grammar color_grammar; - mapnik::expression_grammar expr_grammar; - path_expression_grammar path_expr_grammar; - transform_expression_grammar transform_expr_grammar; - image_filter_grammar > image_filters_grammar; }; diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index 8fe770b6a..86d5d9847 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -423,8 +423,8 @@ void csv_datasource::parse_csv(T & stream, } mapnik::transcoder tr(desc_.get_encoding()); - mapnik::wkt_parser parse_wkt; - mapnik::json::geometry_parser parse_json; + //mapnik::wkt_parser parse_wkt; + //mapnik::json::geometry_parser parse_json; // handle rare case of a single line of data and user-provided headers // where a lack of a newline will mean that std::getline returns false @@ -543,7 +543,7 @@ void csv_datasource::parse_csv(T & stream, break; } - if (parse_wkt.parse(value, feature->paths())) + if (mapnik::from_wkt(value, feature->paths())) { parsed_wkt = true; } @@ -578,7 +578,7 @@ void csv_datasource::parse_csv(T & stream, { break; } - if (parse_json.parse(value.begin(),value.end(), feature->paths())) + if (mapnik::json::from_geojson(value, feature->paths())) { parsed_json = true; } @@ -686,7 +686,7 @@ void csv_datasource::parse_csv(T & stream, (value_length > 1 && !has_dot && value[0] == '0')) { matched = true; - feature->put(fld_name,tr.transcode(value.c_str())); + feature->put(fld_name,std::move(tr.transcode(value.c_str()))); if (feature_count == 1) { desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String)); @@ -732,7 +732,7 @@ void csv_datasource::parse_csv(T & stream, if (!matched) { // fallback to normal string - feature->put(fld_name,tr.transcode(value.c_str())); + feature->put(fld_name,std::move(tr.transcode(value.c_str()))); if (feature_count == 1) { desc_.add_descriptor( diff --git a/src/color_factory.cpp b/src/color_factory.cpp index f183ec3b6..b23e6be37 100644 --- a/src/color_factory.cpp +++ b/src/color_factory.cpp @@ -30,7 +30,7 @@ namespace mapnik { color parse_color(std::string const& str) { - css_color_grammar g; + static css_color_grammar g; return parse_color(str, g); } diff --git a/src/expression.cpp b/src/expression.cpp index 4d2008d5f..f32f9448e 100644 --- a/src/expression.cpp +++ b/src/expression.cpp @@ -35,8 +35,7 @@ namespace mapnik expression_ptr parse_expression(std::string const& str, std::string const& encoding) { - transcoder tr(encoding); - expression_grammar g(tr); + static expression_grammar g; return parse_expression(str, g); } diff --git a/src/image_filter_types.cpp b/src/image_filter_types.cpp index 27d968fce..201564dc6 100644 --- a/src/image_filter_types.cpp +++ b/src/image_filter_types.cpp @@ -46,7 +46,7 @@ bool parse_image_filters(std::string const& filters, std::vector& i { std::string::const_iterator itr = filters.begin(); std::string::const_iterator end = filters.end(); - mapnik::image_filter_grammar > filter_grammar; boost::spirit::qi::ascii::space_type space; bool r = boost::spirit::qi::phrase_parse(itr,end, diff --git a/src/json/geometry_parser.cpp b/src/json/geometry_parser.cpp index 77fe45ab3..fbf9076c0 100644 --- a/src/json/geometry_parser.cpp +++ b/src/json/geometry_parser.cpp @@ -52,7 +52,7 @@ bool geometry_parser::parse(iterator_type first, iterator_type last, b bool from_geojson(std::string const& json, boost::ptr_vector & paths) { - geometry_parser parser; + static geometry_parser parser; std::string::const_iterator start = json.begin(); std::string::const_iterator end = json.end(); return parser.parse(start, end ,paths); diff --git a/src/load_map.cpp b/src/load_map.cpp index a50b68c4b..0bf1f1dc1 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -55,7 +55,7 @@ #include #include #include - +#include // boost #include @@ -467,18 +467,9 @@ void map_parser::parse_style(Map & map, xml_node const& sty) optional filters = sty.get_opt_attr("image-filters"); if (filters) { - std::string::const_iterator itr = filters->begin(); - std::string::const_iterator end = filters->end(); - boost::spirit::qi::ascii::space_type space; - bool result = boost::spirit::qi::phrase_parse(itr,end, - sty.get_tree().image_filters_grammar, - space, - style.image_filters()); - if (!result || itr!=end) - { - throw config_error("failed to parse image-filters: '" + std::string(itr,end) + "'"); + if (!parse_image_filters(*filters, style.image_filters())) { + throw config_error("failed to parse image-filters: '" + *filters + "'"); } - } // direct image filters (applied directly on main image buffer @@ -488,16 +479,8 @@ void map_parser::parse_style(Map & map, xml_node const& sty) optional direct_filters = sty.get_opt_attr("direct-image-filters"); if (direct_filters) { - std::string::const_iterator itr = direct_filters->begin(); - std::string::const_iterator end = direct_filters->end(); - boost::spirit::qi::ascii::space_type space; - bool result = boost::spirit::qi::phrase_parse(itr,end, - sty.get_tree().image_filters_grammar, - space, - style.direct_image_filters()); - if (!result || itr!=end) - { - throw config_error("failed to parse direct-image-filters: '" + std::string(itr,end) + "'"); + if (!parse_image_filters(*direct_filters, style.direct_image_filters())) { + throw config_error("failed to parse direct-image-filters: '" + *direct_filters + "'"); } } @@ -926,7 +909,7 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt) if (geometry_transform_wkt) { mapnik::transform_list_ptr tl = std::make_shared(); - if (!mapnik::parse_transform(*tl, *geometry_transform_wkt, pt.get_tree().transform_expr_grammar)) + if (!mapnik::parse_transform(*tl, *geometry_transform_wkt)) { std::string ss("Could not parse transform from '"); ss += *geometry_transform_wkt + "', expected transform attribute"; @@ -989,12 +972,12 @@ void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym) *file = ensure_relative_to_xml(file); std::string filename = *file; ensure_exists(filename); - put(symbol, keys::file, parse_path(filename, sym.get_tree().path_expr_grammar)); + put(symbol, keys::file, parse_path(filename)); if (image_transform_wkt) { mapnik::transform_list_ptr tl = std::make_shared(); - if (!mapnik::parse_transform(*tl, *image_transform_wkt, sym.get_tree().transform_expr_grammar)) + if (!mapnik::parse_transform(*tl, *image_transform_wkt)) { throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'"); } @@ -1058,7 +1041,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym) if (!filename.empty()) { ensure_exists(filename); - put(symbol,keys::file, parse_path(filename, sym.get_tree().path_expr_grammar)); + put(symbol,keys::file, parse_path(filename)); } // overall opacity to be applied to all paths @@ -1071,7 +1054,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym) if (image_transform_wkt) { mapnik::transform_list_ptr tl = std::make_shared(); - if (!mapnik::parse_transform(*tl, *image_transform_wkt, sym.get_tree().transform_expr_grammar)) + if (!mapnik::parse_transform(*tl, *image_transform_wkt)) { throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'"); } @@ -1139,7 +1122,7 @@ void map_parser::parse_line_pattern_symbolizer(rule & rule, xml_node const & sym file = ensure_relative_to_xml(file); ensure_exists(file); line_pattern_symbolizer symbol; - put(symbol, keys::file, parse_path(file, sym.get_tree().path_expr_grammar)); + put(symbol, keys::file, parse_path(file)); // offset value optional offset = sym.get_opt_attr("offset"); @@ -1181,7 +1164,7 @@ void map_parser::parse_polygon_pattern_symbolizer(rule & rule, file = ensure_relative_to_xml(file); ensure_exists(file); polygon_pattern_symbolizer symbol; - put(symbol, keys::file, parse_path(file, sym.get_tree().path_expr_grammar)); + put(symbol, keys::file, parse_path(file)); // pattern alignment optional p_alignment = sym.get_opt_attr("alignment"); @@ -1239,7 +1222,7 @@ void map_parser::parse_text_symbolizer(rule & rule, xml_node const& sym) if (halo_transform_wkt) { mapnik::transform_list_ptr tl = std::make_shared(); - if (!mapnik::parse_transform(*tl, *halo_transform_wkt, sym.get_tree().transform_expr_grammar)) + if (!mapnik::parse_transform(*tl, *halo_transform_wkt)) { throw mapnik::config_error("Failed to parse halo-transform: '" + *halo_transform_wkt + "'"); } @@ -1279,7 +1262,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym) if (image_transform_wkt) { mapnik::transform_list_ptr tl = std::make_shared(); - if (!mapnik::parse_transform(*tl, *image_transform_wkt, sym.get_tree().transform_expr_grammar)) + if (!mapnik::parse_transform(*tl, *image_transform_wkt)) { throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'"); } @@ -1332,7 +1315,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym) file = ensure_relative_to_xml(file); ensure_exists(file); - put(shield_symbol, keys::file , parse_path(file, sym.get_tree().path_expr_grammar)); + put(shield_symbol, keys::file , parse_path(file)); parse_symbolizer_base(shield_symbol, sym); optional halo_rasterizer_ = sym.get_opt_attr("halo-rasterizer"); if (halo_rasterizer_) put(shield_symbol, keys::halo_rasterizer, halo_rasterizer_enum(*halo_rasterizer_)); diff --git a/src/parse_path.cpp b/src/parse_path.cpp index 26340988c..582ce4fab 100644 --- a/src/parse_path.cpp +++ b/src/parse_path.cpp @@ -40,7 +40,7 @@ namespace mapnik { path_expression_ptr parse_path(std::string const& str) { - path_expression_grammar g; + static path_expression_grammar g; return parse_path(str,g); } diff --git a/src/parse_transform.cpp b/src/parse_transform.cpp index 314fef3c1..58fa617e6 100644 --- a/src/parse_transform.cpp +++ b/src/parse_transform.cpp @@ -36,10 +36,7 @@ transform_list_ptr parse_transform(std::string const& str) transform_list_ptr parse_transform(std::string const& str, std::string const& encoding) { transform_list_ptr tl = std::make_shared(); - transcoder tc(encoding); - expression_grammar ge(tc); - transform_expression_grammar_string gte(ge); - + static transform_expression_grammar_string gte; if (!parse_transform(*tl, str, gte)) { tl.reset(); @@ -47,6 +44,13 @@ transform_list_ptr parse_transform(std::string const& str, std::string const& en return tl; } +bool parse_transform(transform_list& tl, + std::string const& str) +{ + static transform_expression_grammar_string gte; + return parse_transform(tl, str, gte); +} + bool parse_transform(transform_list& transform, std::string const& str, transform_expression_grammar_string const& g) diff --git a/src/transform_expression_grammar.cpp b/src/transform_expression_grammar.cpp index 3f4576077..97b26aa81 100644 --- a/src/transform_expression_grammar.cpp +++ b/src/transform_expression_grammar.cpp @@ -34,7 +34,7 @@ namespace mapnik { namespace qi = boost::spirit::qi; template -transform_expression_grammar::transform_expression_grammar(expression_grammar const& g) +transform_expression_grammar::transform_expression_grammar() : transform_expression_grammar::base_type(start) { using boost::phoenix::construct; @@ -123,8 +123,8 @@ transform_expression_grammar::transform_expression_grammar(expression_ // expressions are separated by a comma. sep_expr = lit(',') >> expr [ _val = _1 ]; - attr = g.attr.alias(); - expr = g.expr.alias(); + attr = g_.attr.alias(); + expr = g_.expr.alias(); } template struct mapnik::transform_expression_grammar; diff --git a/src/wkt/wkt_factory.cpp b/src/wkt/wkt_factory.cpp index 89856ac2f..75368a893 100644 --- a/src/wkt/wkt_factory.cpp +++ b/src/wkt/wkt_factory.cpp @@ -47,7 +47,7 @@ bool wkt_parser::parse(std::string const& wkt, boost::ptr_vector bool from_wkt(std::string const& wkt, boost::ptr_vector & paths) { - wkt_parser parser; + static wkt_parser parser; return parser.parse(wkt,paths); } diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index 0d2d31d3a..7b46e6573 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -21,6 +21,7 @@ *****************************************************************************/ //mapnik +#include #include #include #include @@ -32,6 +33,9 @@ #include #include #include + +#include + // stl #include @@ -96,12 +100,7 @@ struct name_trait< mapnik::enumeration > xml_tree::xml_tree(std::string const& encoding) : node_(*this, ""), file_(), - tr_(encoding), - color_grammar(), - expr_grammar(tr_), - path_expr_grammar(), - transform_expr_grammar(expr_grammar), - image_filters_grammar() + tr_(encoding) { node_.set_processed(true); //root node is always processed }