From 1cf9e31505ff683b1a2b8edfa61bc321848f0636 Mon Sep 17 00:00:00 2001
From: Lars Bilke <lars.bilke@ufz.de>
Date: Thu, 19 Feb 2015 11:20:15 +0100
Subject: [PATCH] More verbose error output when reading GML files.

When attributes are missing the corresponding element is outputted in
a JSON representation. Therefore I added
BaseLib::propertyTreeToString(boost::property_tree::ptree const& tree)

Fixes #590.
---
 BaseLib/StringTools.cpp                     | 20 +++++++++++-----
 BaseLib/StringTools.h                       |  7 ++++++
 FileIO/XmlIO/Boost/BoostXmlGmlInterface.cpp | 26 ++++++++++++---------
 3 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/BaseLib/StringTools.cpp b/BaseLib/StringTools.cpp
index 4e4151f5dda..40019075d50 100644
--- a/BaseLib/StringTools.cpp
+++ b/BaseLib/StringTools.cpp
@@ -14,13 +14,14 @@
 
 #include "StringTools.h"
 
+#include "logog/include/logog.hpp"
+
+#include <boost/property_tree/json_parser.hpp>
+
 #include <algorithm>
 #include <cctype>
 #include <iomanip>
 
-// ThirdParty/logog
-#include "logog/include/logog.hpp"
-
 
 namespace BaseLib
 {
@@ -66,9 +67,9 @@ void simplify(std::string &str)
 {
 	trim (str);
 	str.erase(
-	    std::unique(str.begin(), str.end(), [](char a, char b) { return a == ' ' && b == ' '; }), 
-		str.end() 
-	);  
+	    std::unique(str.begin(), str.end(), [](char a, char b) { return a == ' ' && b == ' '; }),
+		str.end()
+	);
 }
 
 std::string stringToUpper(std::string const& str)
@@ -85,6 +86,13 @@ std::string padLeft(std::string const& str, int maxlen, char ch)
 	return ss.str();
 }
 
+std::string propertyTreeToString(boost::property_tree::ptree const& tree)
+{
+	std::ostringstream ss;
+	boost::property_tree::write_json(ss, tree);
+	return ss.str();
+}
+
 } // end namespace BaseLib
 
 #ifdef MSVC
diff --git a/BaseLib/StringTools.h b/BaseLib/StringTools.h
index 06f09c2e633..521858dba17 100644
--- a/BaseLib/StringTools.h
+++ b/BaseLib/StringTools.h
@@ -15,6 +15,8 @@
 #ifndef STRINGTOOLS_H
 #define STRINGTOOLS_H
 
+#include <boost/property_tree/ptree.hpp>
+
 #include <string>
 #include <list>
 #include <sstream>
@@ -79,6 +81,11 @@ std::string stringToUpper(std::string const& str);
  */
 std::string padLeft(std::string const& str, int maxlen, char ch=' ');
 
+/**
+ * Returns the JSON-representation of the given boost::property_tree.
+ */
+std::string propertyTreeToString(boost::property_tree::ptree const& tree);
+
 } // end namespace BaseLib
 
 #ifdef MSVC
diff --git a/FileIO/XmlIO/Boost/BoostXmlGmlInterface.cpp b/FileIO/XmlIO/Boost/BoostXmlGmlInterface.cpp
index e4717bab6b8..5d5a13e9894 100644
--- a/FileIO/XmlIO/Boost/BoostXmlGmlInterface.cpp
+++ b/FileIO/XmlIO/Boost/BoostXmlGmlInterface.cpp
@@ -20,7 +20,7 @@
 #include <fstream>
 
 #include "logog/include/logog.hpp"
-
+#include "BaseLib/StringTools.h"
 
 namespace FileIO
 {
@@ -55,7 +55,7 @@ bool BoostXmlGmlInterface::readFile(const std::string &fname)
 	ptree doc;
 	read_xml(in, doc, boost::property_tree::xml_parser::no_comments);
 
-	
+
 	if (!isGmlFile(doc))
 		return false;
 
@@ -121,9 +121,10 @@ void BoostXmlGmlInterface::readPoints(boost::property_tree::ptree const & points
 		double   p_z  = static_cast<double>  (point.second.get("<xmlattr>.z",  std::numeric_limits<double>::max()));
 		std::string p_name = point.second.get("<xmlattr>.name", "");
 
-		if ( p_id == std::numeric_limits<unsigned>::max() || p_x == std::numeric_limits<double>::max() || 
-			 p_y  == std::numeric_limits<double>::max()   || p_z == std::numeric_limits<double>::max() ) 
-			WARN("BoostXmlGmlInterface::readPoints(): Attribute missing in <point> tag. Skipping point...")
+		if ( p_id == std::numeric_limits<unsigned>::max() || p_x == std::numeric_limits<double>::max() ||
+			 p_y  == std::numeric_limits<double>::max()   || p_z == std::numeric_limits<double>::max() )
+		WARN("BoostXmlGmlInterface::readPoints(): Skipping point, attribute missing in <point> tag:\n%s",
+			BaseLib::propertyTreeToString(point.second).c_str())
 		else
 		{
 			_idx_map.insert (std::pair<std::size_t, std::size_t>(p_id, points->size()));
@@ -138,7 +139,7 @@ void BoostXmlGmlInterface::readPoints(boost::property_tree::ptree const & points
 	if (pnt_names->empty())
 	{
 		delete pnt_names;
-		pnt_names = nullptr; 
+		pnt_names = nullptr;
 	}
 }
 
@@ -156,7 +157,8 @@ void BoostXmlGmlInterface::readPolylines(boost::property_tree::ptree const& poly
 			continue;
 
 		if (static_cast<unsigned>(polyline.second.get("<xmlattr>.id", std::numeric_limits<unsigned>::max()) == std::numeric_limits<unsigned>::max()))
-			WARN("BoostXmlGmlInterface::readPolylines(): Attribute \"id\" missing in <polyline> tag. Skipping polyline...")
+			WARN("BoostXmlGmlInterface::readPolylines(): Skipping polyline, attribute \"id\" missing in <polyline> tag:\n%s",
+				BaseLib::propertyTreeToString(polyline.second).c_str())
 		else
 		{
 			polylines->push_back(new GeoLib::Polyline(*points));
@@ -177,7 +179,7 @@ void BoostXmlGmlInterface::readPolylines(boost::property_tree::ptree const& poly
 	if (ply_names->empty())
 	{
 		delete ply_names;
-		ply_names = nullptr; 
+		ply_names = nullptr;
 	}
 }
 
@@ -195,7 +197,8 @@ void BoostXmlGmlInterface::readSurfaces(boost::property_tree::ptree const& surfa
 
 		if (static_cast<unsigned>(surface.second.get("<xmlattr>.id", std::numeric_limits<unsigned>::max()) == std::numeric_limits<unsigned>::max()))
 		{
-			WARN("BoostXmlGmlInterface::readSurfaces(): Attribute \"id\" missing in <surface> tag. Skipping surface...")
+			WARN("BoostXmlGmlInterface::readSurfaces(): Skipping surface, attribute \"id\" missing in <surface> tag:\n%s",
+				BaseLib::propertyTreeToString(surface.second).c_str())
 			continue;
 		}
 
@@ -215,7 +218,8 @@ void BoostXmlGmlInterface::readSurfaces(boost::property_tree::ptree const& surfa
 			unsigned p3_attr = static_cast<unsigned>(element.second.get("<xmlattr>.p3", std::numeric_limits<unsigned>::max()));
 
 			if (p1_attr == std::numeric_limits<unsigned>::max() || p2_attr == std::numeric_limits<unsigned>::max() || p3_attr == std::numeric_limits<unsigned>::max())
-				WARN("BoostXmlGmlInterface::readSurfaces(): Attribute missing in <element> tag. Skipping triangle...");
+				WARN("BoostXmlGmlInterface::readSurfaces(): Skipping triangle, attribute missing in <element> tag:\n%s",
+					BaseLib::propertyTreeToString(element.second).c_str())
 			{
 				std::size_t p1 = pnt_id_map[_idx_map[p1_attr]];
 				std::size_t p2 = pnt_id_map[_idx_map[p2_attr]];
@@ -229,7 +233,7 @@ void BoostXmlGmlInterface::readSurfaces(boost::property_tree::ptree const& surfa
 	if (sfc_names->empty())
 	{
 		delete sfc_names;
-		sfc_names = nullptr; 
+		sfc_names = nullptr;
 	}
 }
 
-- 
GitLab