initial commit - make parse and parse_from_string return boolean ,collect error messages

This commit is contained in:
artemp 2015-07-14 19:45:50 +02:00
parent 6d6cb15b45
commit a46af76216
4 changed files with 103 additions and 24 deletions

View file

@ -38,15 +38,18 @@ namespace mapnik { namespace svg {
class MAPNIK_DECL svg_parser : private util::noncopyable
{
using error_message_container = std::vector<std::string> ;
public:
explicit svg_parser(svg_converter_type & path);
~svg_parser();
void parse(std::string const& filename);
void parse_from_string(std::string const& svg);
error_message_container const& error_messages() const;
bool parse(std::string const& filename);
bool parse_from_string(std::string const& svg);
svg_converter_type & path_;
bool is_defs_;
std::map<std::string, gradient> gradient_map_;
std::pair<std::string, gradient> temporary_gradient_;
error_message_container error_messages_;
};
}}

View file

@ -0,0 +1,54 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2015 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_SVG_PARSER_EXCEPTION_HPP
#define MAPNIK_SVG_PARSER_EXCEPTION_HPP
// mapnik
#include <mapnik/config.hpp>
#include <exception>
// stl
#include <map>
namespace mapnik { namespace svg {
class MAPNIK_DECL svg_parser_exception : public std::exception
{
public:
svg_parser_exception(std::string const& message)
: message_(message) {}
~svg_parser_exception() throw() {}
virtual const char* what() const throw()
{
return message_.c_str();
}
private:
std::string message_;
};
}}
#endif // MAPNIK_SVG_PARSER_EXCEPTION_HPP

View file

@ -175,7 +175,15 @@ std::shared_ptr<mapnik::marker const> marker_cache::find(std::string const& uri,
svg_path_adapter svg_path(stl_storage);
svg_converter_type svg(svg_path, marker_path->attributes());
svg_parser p(svg);
p.parse_from_string(known_svg_string);
if (!p.parse_from_string(known_svg_string))
{
for (auto const& msg : p.error_messages())
{
std::cerr << "SVG PARSING ERROR:\"" << msg << "\"" << std::endl;
}
return std::make_shared<mapnik::marker const>(mapnik::marker_null());
}
//svg.arrange_orientations();
double lox,loy,hix,hiy;
svg.bounding_rect(&lox, &loy, &hix, &hiy);

View file

@ -26,7 +26,7 @@
#include <mapnik/svg/svg_path_parser.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/safe_cast.hpp>
#include <mapnik/svg/svg_parser_exception.hpp>
#include "agg_ellipse.h"
#include "agg_rounded_rect.h"
#include "agg_span_gradient.h"
@ -99,7 +99,8 @@ struct key_value_sequence_ordered
qi::rule<Iterator, std::string(), SkipType> key, value;
};
agg::rgba8 parse_color(const char* str)
template <typename T>
agg::rgba8 parse_color(T & error_messages, const char* str)
{
mapnik::color c(100,100,100);
try
@ -108,7 +109,7 @@ agg::rgba8 parse_color(const char* str)
}
catch (mapnik::config_error const& ex)
{
MAPNIK_LOG_ERROR(svg_parser) << ex.what();
error_messages.emplace_back(ex.what());
}
return agg::rgba8(c.red(), c.green(), c.blue(), c.alpha());
}
@ -330,12 +331,14 @@ void parse_attr(svg_parser & parser, const xmlChar * name, const xmlChar * value
}
else
{
MAPNIK_LOG_ERROR(svg_parser) << "Failed to find gradient fill: " << id;
std::stringstream ss;
ss << "Failed to find gradient fill: " << id;
parser.error_messages_.push_back(ss.str());
}
}
else
{
parser.path_.fill(parse_color((const char*) value));
parser.path_.fill(parse_color(parser.error_messages_, (const char*) value));
}
}
else if (xmlStrEqual(name, BAD_CAST "fill-opacity"))
@ -367,12 +370,14 @@ void parse_attr(svg_parser & parser, const xmlChar * name, const xmlChar * value
}
else
{
MAPNIK_LOG_ERROR(svg_parser) << "Failed to find gradient fill: " << id;
std::stringstream ss;
ss << "Failed to find gradient fill: " << id;
parser.error_messages_.push_back(ss.str());
}
}
else
{
parser.path_.stroke(parse_color((const char*) value));
parser.path_.stroke(parse_color(parser.error_messages_, (const char*) value));
}
}
else if (xmlStrEqual(name, BAD_CAST "stroke-width"))
@ -519,7 +524,6 @@ void parse_path(svg_parser & parser, xmlTextReaderPtr reader)
void parse_polygon(svg_parser & parser, xmlTextReaderPtr reader)
{
xmlChar *value;
value = xmlTextReaderGetAttribute(reader, BAD_CAST "points");
if (value)
{
@ -815,7 +819,7 @@ void parse_gradient_stop(svg_parser & parser, xmlTextReaderPtr reader)
}
catch (mapnik::config_error const& ex)
{
MAPNIK_LOG_ERROR(svg_parser) << ex.what();
parser.error_messages_.emplace_back(ex.what());
}
}
else if (kv.first == "stop-opacity")
@ -835,7 +839,7 @@ void parse_gradient_stop(svg_parser & parser, xmlTextReaderPtr reader)
}
catch (mapnik::config_error const& ex)
{
MAPNIK_LOG_ERROR(svg_parser) << ex.what();
parser.error_messages_.emplace_back(ex.what());
}
xmlFree(value);
}
@ -893,7 +897,9 @@ bool parse_common_gradient(svg_parser & parser, xmlTextReaderPtr reader)
}
else
{
MAPNIK_LOG_ERROR(svg_parser) << "Failed to find linked gradient " << linkid;
std::stringstream ss;
ss << "Failed to find linked gradient " << linkid;
parser.error_messages_.push_back(ss.str());
}
}
xmlFree(value);
@ -1062,32 +1068,40 @@ svg_parser::svg_parser(svg_converter<svg_path_adapter,
svg_parser::~svg_parser() {}
void svg_parser::parse(std::string const& filename)
bool svg_parser::parse(std::string const& filename)
{
xmlTextReaderPtr reader = xmlNewTextReaderFilename(filename.c_str());
if (reader == nullptr)
{
MAPNIK_LOG_ERROR(svg_parser) << "Unable to open '" << filename << "'";
std::stringstream ss;
ss << "Unable to open '" << filename << "'";
error_messages_.push_back(ss.str());
}
else if (!parse_reader(*this,reader))
{
MAPNIK_LOG_ERROR(svg_parser) << "Unable to parse '" << filename << "'";
std::stringstream ss;
ss << "Unable to parse '" << filename << "'";
error_messages_.push_back(ss.str());
}
return error_messages_.empty() ? true : false;
}
void svg_parser::parse_from_string(std::string const& svg)
bool svg_parser::parse_from_string(std::string const& svg)
{
xmlTextReaderPtr reader = xmlReaderForMemory(svg.c_str(),safe_cast<int>(svg.size()),nullptr,nullptr,
(XML_PARSE_NOBLANKS | XML_PARSE_NOCDATA | XML_PARSE_NOERROR | XML_PARSE_NOWARNING));
if (reader == nullptr)
if (reader == nullptr ||!parse_reader(*this,reader))
{
MAPNIK_LOG_ERROR(svg_parser) << "Unable to parse '" << svg << "'";
}
else if (!parse_reader(*this,reader))
{
MAPNIK_LOG_ERROR(svg_parser) << "Unable to parse '" << svg << "'";
std::stringstream ss;
ss << "Unable to parse '" << svg << "'";
error_messages_.push_back(ss.str());
}
return error_messages_.empty() ? true : false;
}
svg_parser::error_message_container const& svg_parser::error_messages() const
{
return error_messages_;
}
}}