tue_config
xml.cpp
Go to the documentation of this file.
1 #include <fstream>
2 #include <sstream>
3 #include <tinyxml2.h>
4 
7 #include "tue/config/read.h"
8 #include "loader_functions.h"
9 
10 #include "tue/filesystem/path.h"
11 
12 namespace tue
13 {
14 
15 namespace config
16 {
17 
18 bool setValue(const std::string& key, const std::string& value, ReaderWriter& config)
19 {
20  char* pEnd;
21  int i = (int) std::strtol(value.c_str(), &pEnd, 10);
22  if (pEnd[0] == 0)
23  {
24  config.setValue(key, i);
25  return true;
26  }
27 
28  double d = std::strtod(value.c_str(), &pEnd);
29  if (pEnd[0] == 0)
30  {
31  config.setValue(key, d);
32  return true;
33  }
34 
35  bool b = false;
36  if (strToBool(value, b))
37  {
38  config.setValue(key, b);
39  return true;
40  }
41 
42  config.setValue(key, value);
43  return true;
44 }
45 
46 // ----------------------------------------------------------------------------------------------------
47 
48 bool loadFromXMLText(const tinyxml2::XMLElement& element, ReaderWriter& config)
49 {
50  std::string key(element.Value());
51  if (element.GetText() == nullptr)
52  {
53  std::cout << "Empty key: " << key << std::endl;
54  return setValue(key, "", config);
55  }
56  std::string value(element.GetText());
57  return setValue(key, value, config);
58 }
59 
60 // ----------------------------------------------------------------------------------------------------
61 
62 bool loadFromXMLElement(const tinyxml2::XMLElement& element, ReaderWriter& config)
63 {
64  // Attributes aren't read, if element doesn't have any child elements
65  if (element.FirstChildElement() == nullptr)
66  {
67  return loadFromXMLText(element, config);
68  }
69  else
70  {
71  // Start a new array with the Value of the current element as key
72  std::string element_name = element.Value();
73  config.writeArray(element_name);
74 
75  // Iterate through attributes
76  // if this element does not contain children, we don't end up here
77  for (const tinyxml2::XMLAttribute* attribute = element.FirstAttribute(); attribute != nullptr; attribute = attribute->Next())
78  {
80  setValue(attribute->Name(), attribute->Value(), config);
82  }
83 
84  // Iterate through elements
85  for(const tinyxml2::XMLElement* e = element.FirstChildElement(); e != nullptr; e = e->NextSiblingElement())
86  {
87  std::string candidate_name = e->Value();
89 
90  if (!loadFromXMLElement(*e, config))
91  {
92  std::stringstream error;
93  error << "Error parsing " << candidate_name;
94  config.addError(error.str());
95  std::cout << error.str() << std::endl;
96  return false;
97  }
99  }
100  config.endArray();
101  }
102 
103  return true;
104 
105 }
106 
107 // ----------------------------------------------------------------------------------------------------
108 
109 bool loadFromXMLDocument(const tinyxml2::XMLDocument& doc, ReaderWriter& config)
110 {
111  const tinyxml2::XMLElement* root = doc.FirstChildElement();
112 
113  if (root->NextSibling() != nullptr)
114  {
115  throw tue::config::ParseException("A valid XML file should only contain one root element");
116  }
117 
118  return loadFromXMLElement(*root, config);
119 }
120 
121 // ----------------------------------------------------------------------------------------------------
122 
124 {
125  tinyxml2::XMLDocument doc;
126  std::string stream_string;
127  stream >> stream_string;
128  doc.Parse(stream_string.c_str());
129  if (doc.Error())
130  {
131  std::stringstream error;
132  error << "Error loading stream:" << std::endl << stream.rdbuf() << std::endl;
133  error << doc.ErrorStr() << " at line " << doc.ErrorLineNum();
134  config.addError(error.str());
135  return false;
136  }
137  return loadFromXMLDocument(doc, config);
138 }
139 
140 // ----------------------------------------------------------------------------------------------------
141 
143 {
144  tinyxml2::XMLDocument doc;
145  doc.Parse(string.c_str());
146  if (doc.Error())
147  {
148  std::stringstream error;
149  error << "Error loading string:" << std::endl << string << std::endl;
150  error << doc.ErrorStr() << " at line " << doc.ErrorLineNum();
151  config.addError(error.str());
152  return false;
153  }
154  return loadFromXMLDocument(doc, config);
155 }
156 
157 // ----------------------------------------------------------------------------------------------------
158 
160 {
161  config.setSource(filename);
162 
163  tue::filesystem::Path path(filename);
164  if (!path.exists())
165  {
166  std::stringstream error;
167  error << "[loadFromXMLFile] file '" << filename << "' doesn't exist." << std::endl;
168  config.addError(error.str());
169  return false;
170  }
171 
172  // Load the file
173  tinyxml2::XMLDocument doc;
174  doc.LoadFile(filename.c_str());
175  if (doc.Error())
176  {
177  std::stringstream error;
178  error << "Error loading " << filename << ": ";
179  error << doc.ErrorStr() << " at row " << doc.ErrorLineNum();
180  config.addError(error.str());
181  return false;
182  }
183 
184  // read the document
185  return loadFromXMLDocument(doc, config);
186 }
187 
188 // ----------------------------------------------------------------------------------------------------
189 
190 } // End of namespace config
191 
192 } // End of namespace tue
std::strtol
T strtol(T... args)
sstream
std::istream::rdbuf
T rdbuf(T... args)
fstream
std::string
tue::config::loadFromXMLText
bool loadFromXMLText(const tinyxml2::XMLElement &element, ReaderWriter &config)
loadFromXMLText writes a value from xml element into config object. Stored as double,...
Definition: xml.cpp:48
tue::config::ReaderWriter::setSource
void setSource(const std::string &source)
setSource set the source file of the data in this object
Definition: reader_writer.h:193
tue::config::ReaderWriter::endArrayItem
bool endArrayItem()
endArrayItem go back to the array level
Definition: reader_writer.cpp:245
tue::config::loadFromXMLFile
bool loadFromXMLFile(const std::string &filename, ReaderWriter &config)
loadFromXMLFile loads a xml file into a ReaderWriter class
Definition: xml.cpp:159
tue::filesystem::Path
std::stringstream
tue::config::strToBool
bool strToBool(std::string s, bool &rhs)
strToBool Converts a string to a boolean of matches one of the following: y, n, yes,...
Definition: loader_functions.cpp:10
tue::config::ReaderWriter::writeArray
bool writeArray(const std::string &name)
writeArray starts writing an array. Or start extending it, if it already exists.
Definition: reader_writer.cpp:202
tue::filesystem::Path::exists
bool exists() const
tue::config::ParseException
Definition: read.h:17
tue::config::loadFromXMLDocument
bool loadFromXMLDocument(const tinyxml2::XMLDocument &doc, ReaderWriter &config)
Definition: xml.cpp:109
xml.h
tue::config::ReaderWriter::addArrayItem
bool addArrayItem()
addArrayItem create a new item in the array
Definition: reader_writer.cpp:223
std::cout
tue::config::ReaderWriter
Definition: reader_writer.h:26
loader_functions.h
std::string::c_str
T c_str(T... args)
tue::config::setValue
bool setValue(const std::string &key, const std::string &value, ReaderWriter &config)
setValue sets the value as a double, int or string
Definition: xml.cpp:18
tue::config::loadFromXMLElement
bool loadFromXMLElement(const tinyxml2::XMLElement &element, ReaderWriter &config)
Definition: xml.cpp:62
tue::config::ReaderWriter::endArray
bool endArray()
endArray go to parrent of current array, wrapping end() for readibility
Definition: reader_writer.h:98
tue::config::ReaderWriter::addError
void addError(const std::string &msg)
Definition: reader_writer.cpp:136
path.h
tue::config::ReaderWriter::setValue
void setValue(const std::string &name, const T &value)
setValue set child value with key 'name' and value 'value'
Definition: reader_writer.h:155
std::endl
T endl(T... args)
std::strtod
T strtod(T... args)
configuration.h
std::stringstream::str
T str(T... args)
tue::config::loadFromXMLString
bool loadFromXMLString(const std::string &string, ReaderWriter &config)
loadFromXMLString loads a xml string into a ReaderWriter class
Definition: xml.cpp:142
std::istream
tue
tue::config::loadFromXMLStream
bool loadFromXMLStream(std::istream &stream, ReaderWriter &config)
loadFromXMLStream loads a xml stream into a ReaderWriter class
Definition: xml.cpp:123
read.h
config
tue::config::ReaderWriter config
Definition: sdf_gtest.cpp:9