remove all remaining stringstream usage in load_map to avoid perf hit from locale lock - refs #1055

This commit is contained in:
Dane Springmeyer 2012-12-06 20:15:27 -08:00
parent 0e49aa039e
commit 390706b8c7
5 changed files with 63 additions and 51 deletions

View file

@ -100,6 +100,7 @@ public:
void set_processed(bool processed) const;
unsigned line() const;
std::string line_to_string() const;
const_iterator begin() const;
const_iterator end() const;

View file

@ -1,5 +1,6 @@
#include <mapnik/config_error.hpp>
#include <mapnik/xml_tree.hpp>
#include <mapnik/util/conversions.hpp>
namespace mapnik
{
@ -38,12 +39,23 @@ config_error::config_error(std::string const& what,
char const* config_error::what() const throw()
{
std::stringstream s;
s << what_;
if (!node_name_.empty()) s << " in " << node_name_;
if (line_number_ > 0) s << " at line " << line_number_;
if (!file_.empty()) s << " of '" << file_ << "'";
msg_ = s.str(); //Avoid returning pointer to dead object
msg_ = what_;
if (!node_name_.empty())
{
msg_ += " in " + node_name_;
}
if (line_number_ > 0)
{
std::string number;
if (util::to_string(number,line_number_))
{
msg_ += " at line " + number;
}
}
if (!file_.empty())
{
msg_ += " of '" + file_ + "'";
}
return msg_.c_str();
}

View file

@ -39,9 +39,6 @@
#include <libxml/parserInternals.h>
#include <libxml/xinclude.h>
// stl
#include <iostream>
using namespace std;
#define DEFAULT_OPTIONS (XML_PARSE_NOERROR | XML_PARSE_NOENT | XML_PARSE_NOBLANKS | XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA)
@ -88,11 +85,10 @@ public:
xmlError * error = xmlCtxtGetLastError(ctx_);
if (error)
{
std::ostringstream os;
os << "XML document not well formed";
os << ": " << std::endl << error->message;
std::string msg("XML document not well formed:\n");
msg += error->message;
// remove CR
std::string msg = os.str().substr(0, os.str().size() - 1);
msg = msg.substr(0, msg.size() - 1);
throw config_error(msg, error->line, error->file);
}
}
@ -132,18 +128,18 @@ public:
{
if (!doc)
{
std::string msg("XML document not well formed");
xmlError * error = xmlCtxtGetLastError( ctx_ );
std::ostringstream os;
os << "XML document not well formed";
int line=0;
std::string file;
if (error)
{
os << ": " << std::endl << error->message;
line = error->line;
file = error->file;
msg += ":\n";
msg += error->message;
throw config_error(msg, error->line, error->file);
}
else
{
throw config_error(msg);
}
throw config_error(os.str(), line, file);
}
int iXIncludeReturn = xmlXIncludeProcessFlags(doc, options_);

View file

@ -63,10 +63,6 @@
// agg
#include "agg_trans_affine.h"
// stl
#include <iostream>
#include <sstream>
using boost::tokenizer;
using std::endl;
@ -113,7 +109,7 @@ private:
void ensure_font_face(std::string const& face_name);
void find_unused_nodes(xml_node const& root);
void find_unused_nodes_recursive(xml_node const& node, std::stringstream &error_text);
void find_unused_nodes_recursive(xml_node const& node, std::string & error_text);
std::string ensure_relative_to_xml(boost::optional<std::string> opt_path);
@ -222,15 +218,15 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas
}
else
{
std::ostringstream s_err;
s_err << "failed to parse Map maximum-extent '" << *maximum_extent << "'";
std::string s_err("failed to parse Map maximum-extent '");
s_err += *maximum_extent + "'";
if (strict_)
{
throw config_error(s_err.str());
throw config_error(s_err);
}
else
{
MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err.str();
MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err;
}
}
}
@ -622,15 +618,15 @@ void map_parser::parse_layer(Map & map, xml_node const& node)
}
else
{
std::ostringstream s_err;
s_err << "failed to parse Layer maximum-extent '" << *maximum_extent << "' for '" << name << "'";
std::string s_err("failed to parse Layer maximum-extent '");
s_err += *maximum_extent + "' for '" + name + "'";
if (strict_)
{
throw config_error(s_err.str());
throw config_error(s_err);
}
else
{
MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err.str();
MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err;
}
}
}
@ -646,15 +642,15 @@ void map_parser::parse_layer(Map & map, xml_node const& node)
std::string style_name = child->get_text();
if (style_name.empty())
{
std::ostringstream ss;
ss << "StyleName is empty in Layer: '" << lyr.name() << "'";
std::string ss("StyleName is empty in Layer: '");
ss += lyr.name() + "'";
if (strict_)
{
throw config_error(ss.str());
throw config_error(ss);
}
else
{
MAPNIK_LOG_WARN(load_map) << "map_parser: " << ss.str();
MAPNIK_LOG_WARN(load_map) << "map_parser: " << ss;
}
}
else
@ -854,10 +850,9 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt)
mapnik::transform_list_ptr tl = boost::make_shared<mapnik::transform_list>();
if (!mapnik::parse_transform(*tl, *geometry_transform_wkt, pt.get_tree().transform_expr_grammar))
{
std::stringstream ss;
ss << "Could not parse transform from '" << *geometry_transform_wkt
<< "', expected transform attribute";
throw config_error(ss.str());
std::string ss("Could not parse transform from '");
ss += *geometry_transform_wkt + "', expected transform attribute";
throw config_error(ss);
}
sym.set_transform(tl);
}
@ -1674,11 +1669,11 @@ void map_parser::ensure_exists(std::string const& file_path)
void map_parser::find_unused_nodes(xml_node const& root)
{
std::stringstream error_message;
std::string error_message;
find_unused_nodes_recursive(root, error_message);
if (!error_message.str().empty())
if (!error_message.empty())
{
std::string msg("Unable to process some data while parsing '" + filename_ + "':" + error_message.str());
std::string msg("Unable to process some data while parsing '" + filename_ + "':" + error_message);
if (strict_)
{
throw config_error(msg);
@ -1690,14 +1685,14 @@ void map_parser::find_unused_nodes(xml_node const& root)
}
}
void map_parser::find_unused_nodes_recursive(xml_node const& node, std::stringstream &error_message)
void map_parser::find_unused_nodes_recursive(xml_node const& node, std::string & error_message)
{
if (!node.processed())
{
if (node.is_text()) {
error_message << "\n* text '" << node.text() << "'";
error_message += "\n* text '" + node.text() + "'";
} else {
error_message << "\n* node '" << node.name() << "' at line " << node.line();
error_message += "\n* node '" + node.name() + "' at line " + node.line_to_string();
}
return; //All attributes and children are automatically unprocessed, too.
}
@ -1708,9 +1703,9 @@ void map_parser::find_unused_nodes_recursive(xml_node const& node, std::stringst
{
if (!aitr->second.processed)
{
error_message << "\n* attribute '" << aitr->first <<
"' with value '" << aitr->second.value <<
"' at line " << node.line();
error_message += "\n* attribute '" + aitr->first +
"' with value '" + aitr->second.value +
"' at line " + node.line_to_string();
}
}
xml_node::const_iterator itr = node.begin();

View file

@ -448,6 +448,14 @@ unsigned xml_node::line() const
return line_;
}
std::string xml_node::line_to_string() const
{
std::string number;
util::to_string(number,line_);
return number;
}
#define compile_get_opt_attr(T) template boost::optional<T> xml_node::get_opt_attr<T>(std::string const&) const
#define compile_get_attr(T) template T xml_node::get_attr<T>(std::string const&) const; template T xml_node::get_attr<T>(std::string const&, T const&) const
#define compile_get_value(T) template T xml_node::get_value<T>() const