diff --git a/include/mapnik/ptree_helpers.hpp b/include/mapnik/ptree_helpers.hpp index 7d5ae09a6..aa9c311f4 100644 --- a/include/mapnik/ptree_helpers.hpp +++ b/include/mapnik/ptree_helpers.hpp @@ -27,11 +27,11 @@ #include #include #include - +#include // boost #include -#include #include +#include // stl #include @@ -39,6 +39,9 @@ namespace mapnik { +template +static boost::optional fast_cast(std::string const& value); + template T get(boost::property_tree::ptree const& node, std::string const& name, bool is_attribute, T const& default_value); @@ -205,6 +208,39 @@ struct name_trait< mapnik::enumeration > } }; +template +boost::optional fast_cast(std::string const& value) +{ + return boost::lexical_cast( value ); +} + +template <> +boost::optional fast_cast(std::string const& value) +{ + int result; + if (mapnik::conversions::string2int(value,&result)) + return boost::optional(result); + return boost::optional(); +} + +template <> +boost::optional fast_cast(std::string const& value) +{ + double result; + if (mapnik::conversions::string2double(value,&result)) + return boost::optional(result); + return boost::optional(); +} + +template <> +boost::optional fast_cast(std::string const& value) +{ + float result; + if (mapnik::conversions::string2float(value,&result)) + return boost::optional(result); + return boost::optional(); +} + template T get(boost::property_tree::ptree const& node, std::string const& name, @@ -223,11 +259,12 @@ T get(boost::property_tree::ptree const& node, if ( str ) { - try + boost::optional result = fast_cast(*str); + if (result) { - return boost::lexical_cast( * str ); + return *result; } - catch (const boost::bad_lexical_cast & ) + else { throw config_error(std::string("Failed to parse ") + (is_attribute ? "attribute" : "child node") + " '" + @@ -296,11 +333,12 @@ T get(boost::property_tree::ptree const& node, std::string const& name, bool is_ (is_attribute ? "attribute " : "child node ") + "'" + name + "' is missing"); } - try + boost::optional result = fast_cast(*str); + if (result) { - return boost::lexical_cast( *str ); + return *result; } - catch (const boost::bad_lexical_cast & ) + else { throw config_error(std::string("Failed to parse ") + (is_attribute ? "attribute" : "child node") + " '" + @@ -352,11 +390,8 @@ boost::optional get_optional(boost::property_tree::ptree const& node, std::st boost::optional result; if ( str ) { - try - { - result = boost::lexical_cast( *str ); - } - catch (const boost::bad_lexical_cast &) + result = fast_cast(*str); + if (!result) { throw config_error(std::string("Failed to parse ") + (is_attribute ? "attribute" : "child node") + " '" + @@ -388,7 +423,6 @@ inline boost::optional get_optional(boost::property_tree::ptree const& no { try { - //result = boost::lexical_cast( *str ); result = mapnik::color_factory::from_string((*str).c_str()); } catch (...) diff --git a/include/mapnik/util/conversions.hpp b/include/mapnik/util/conversions.hpp index 5dbfb3161..a5defe261 100644 --- a/include/mapnik/util/conversions.hpp +++ b/include/mapnik/util/conversions.hpp @@ -69,7 +69,7 @@ static bool string2double(std::string const& value, double * result) return r && (str_beg == str_end); } -static bool string2int(const char * value, double * result) +static bool string2double(const char * value, double * result) { size_t length = strlen(value); if (length < 1 || value == NULL) @@ -81,6 +81,27 @@ static bool string2int(const char * value, double * result) return r && (iter == end); } +static bool string2float(std::string const& value, float * result) +{ + if (value.empty()) + return false; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = qi::phrase_parse(str_beg,str_end,qi::float_,ascii::space,*result); + return r && (str_beg == str_end); +} + +static bool string2float(const char * value, float * result) +{ + size_t length = strlen(value); + if (length < 1 || value == NULL) + return false; + const char *begin = value; + const char *iter = begin; + const char *end = value + length; + bool r = qi::phrase_parse(iter,end,qi::float_,ascii::space,*result); + return r && (iter == end); +} } }