initial commit - make parse and parse_from_string return boolean ,collect error messages
This commit is contained in:
parent
6d6cb15b45
commit
a46af76216
4 changed files with 103 additions and 24 deletions
|
@ -38,15 +38,18 @@ namespace mapnik { namespace svg {
|
||||||
|
|
||||||
class MAPNIK_DECL svg_parser : private util::noncopyable
|
class MAPNIK_DECL svg_parser : private util::noncopyable
|
||||||
{
|
{
|
||||||
|
using error_message_container = std::vector<std::string> ;
|
||||||
public:
|
public:
|
||||||
explicit svg_parser(svg_converter_type & path);
|
explicit svg_parser(svg_converter_type & path);
|
||||||
~svg_parser();
|
~svg_parser();
|
||||||
void parse(std::string const& filename);
|
error_message_container const& error_messages() const;
|
||||||
void parse_from_string(std::string const& svg);
|
bool parse(std::string const& filename);
|
||||||
|
bool parse_from_string(std::string const& svg);
|
||||||
svg_converter_type & path_;
|
svg_converter_type & path_;
|
||||||
bool is_defs_;
|
bool is_defs_;
|
||||||
std::map<std::string, gradient> gradient_map_;
|
std::map<std::string, gradient> gradient_map_;
|
||||||
std::pair<std::string, gradient> temporary_gradient_;
|
std::pair<std::string, gradient> temporary_gradient_;
|
||||||
|
error_message_container error_messages_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
54
include/mapnik/svg/svg_parser_exception.hpp
Normal file
54
include/mapnik/svg/svg_parser_exception.hpp
Normal 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
|
|
@ -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_path_adapter svg_path(stl_storage);
|
||||||
svg_converter_type svg(svg_path, marker_path->attributes());
|
svg_converter_type svg(svg_path, marker_path->attributes());
|
||||||
svg_parser p(svg);
|
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();
|
//svg.arrange_orientations();
|
||||||
double lox,loy,hix,hiy;
|
double lox,loy,hix,hiy;
|
||||||
svg.bounding_rect(&lox, &loy, &hix, &hiy);
|
svg.bounding_rect(&lox, &loy, &hix, &hiy);
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <mapnik/svg/svg_path_parser.hpp>
|
#include <mapnik/svg/svg_path_parser.hpp>
|
||||||
#include <mapnik/config_error.hpp>
|
#include <mapnik/config_error.hpp>
|
||||||
#include <mapnik/safe_cast.hpp>
|
#include <mapnik/safe_cast.hpp>
|
||||||
|
#include <mapnik/svg/svg_parser_exception.hpp>
|
||||||
#include "agg_ellipse.h"
|
#include "agg_ellipse.h"
|
||||||
#include "agg_rounded_rect.h"
|
#include "agg_rounded_rect.h"
|
||||||
#include "agg_span_gradient.h"
|
#include "agg_span_gradient.h"
|
||||||
|
@ -99,7 +99,8 @@ struct key_value_sequence_ordered
|
||||||
qi::rule<Iterator, std::string(), SkipType> key, value;
|
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);
|
mapnik::color c(100,100,100);
|
||||||
try
|
try
|
||||||
|
@ -108,7 +109,7 @@ agg::rgba8 parse_color(const char* str)
|
||||||
}
|
}
|
||||||
catch (mapnik::config_error const& ex)
|
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());
|
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
|
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
|
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"))
|
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
|
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
|
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"))
|
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)
|
void parse_polygon(svg_parser & parser, xmlTextReaderPtr reader)
|
||||||
{
|
{
|
||||||
xmlChar *value;
|
xmlChar *value;
|
||||||
|
|
||||||
value = xmlTextReaderGetAttribute(reader, BAD_CAST "points");
|
value = xmlTextReaderGetAttribute(reader, BAD_CAST "points");
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
|
@ -815,7 +819,7 @@ void parse_gradient_stop(svg_parser & parser, xmlTextReaderPtr reader)
|
||||||
}
|
}
|
||||||
catch (mapnik::config_error const& ex)
|
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")
|
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)
|
catch (mapnik::config_error const& ex)
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_ERROR(svg_parser) << ex.what();
|
parser.error_messages_.emplace_back(ex.what());
|
||||||
}
|
}
|
||||||
xmlFree(value);
|
xmlFree(value);
|
||||||
}
|
}
|
||||||
|
@ -893,7 +897,9 @@ bool parse_common_gradient(svg_parser & parser, xmlTextReaderPtr reader)
|
||||||
}
|
}
|
||||||
else
|
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);
|
xmlFree(value);
|
||||||
|
@ -1062,32 +1068,40 @@ svg_parser::svg_parser(svg_converter<svg_path_adapter,
|
||||||
|
|
||||||
svg_parser::~svg_parser() {}
|
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());
|
xmlTextReaderPtr reader = xmlNewTextReaderFilename(filename.c_str());
|
||||||
if (reader == nullptr)
|
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))
|
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,
|
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));
|
(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 << "'";
|
std::stringstream ss;
|
||||||
}
|
ss << "Unable to parse '" << svg << "'";
|
||||||
else if (!parse_reader(*this,reader))
|
error_messages_.push_back(ss.str());
|
||||||
{
|
|
||||||
MAPNIK_LOG_ERROR(svg_parser) << "Unable to parse '" << svg << "'";
|
|
||||||
}
|
}
|
||||||
|
return error_messages_.empty() ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svg_parser::error_message_container const& svg_parser::error_messages() const
|
||||||
|
{
|
||||||
|
return error_messages_;
|
||||||
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
Loading…
Reference in a new issue