OpenLB 1.7
Loading...
Searching...
No Matches
xmlReader.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2010 Jonas Latt, Jonas Fietz, Mathias Krause
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
27#ifndef XML_IO_H
28#define XML_IO_H
29
30#include <string>
31#include <vector>
32#include <iostream>
33#include <sstream>
34#include <map>
35#include <typeinfo>
36
37#include <tinyxml.h>
38
39#include "io/ostreamManager.h"
41#include "xmlReaderOutput.h"
42
43namespace olb {
44
45namespace util {
46 template <class T, unsigned DIM> class ADf;
47}
48
49class XMLreader {
51public:
56 XMLreader( TiXmlNode* pParent, OutputChannel outputChannel = OutputChannel::ERRCHANNEL);
58 XMLreader( const std::string& fName, OutputChannel outputChannel = OutputChannel::ERRCHANNEL);
60 ~XMLreader();
62 //void print(int indent) const;
68 //bool read(bool& value, bool verbose = true) const;
69 template <typename T> bool read(T& value, bool verboseOn = true, bool exitIfMissing=false) const;
70 template <typename T,unsigned DIM> bool read(util::ADf<T,DIM>& value, bool verboseOn = true, bool exitIfMissing=false) const;
71 template <typename T> bool read(std::vector<T>& value, bool verboseOn = true, bool exitIfMissing=false) const;
72 template <typename T> T get(bool verboseOn = true, bool exitIfMissing=false) const;
75 template<typename ParameterType>
76 bool readOrWarn(std::string name_parameter_1,
77 std::string name_parameter_2, std::string name_parameter_3,
78 ParameterType& var, bool defaultAvailable = true, bool exitIfMissing = false, bool showWarning = true) const;
80 template<typename ParameterType>
81 bool readOrWarn(std::string name_parameter_1,
82 std::string name_parameter_2, std::string name_parameter_3, std::string name_parameter_4,
83 ParameterType& var, bool defaultAvailable = true, bool exitIfMissing = false, bool showWarning = true) const;
85 XMLreader const& operator[] (std::string name) const;
90 std::vector<XMLreader*>::const_iterator begin() const;
95 std::vector<XMLreader*>::const_iterator end() const;
97 void setWarningsOn(bool warnings) const;
99 std::string getName() const;
101 std::string getText() const;
103 std::string getAttribute(const std::string& aName) const;
104
107private:
108 void mainProcessorIni(TiXmlNode* pParent);
109 void slaveProcessorIni();
110 XMLreader();
111private:
112 mutable bool _warningsOn;
113 std::string _text;
114 std::string _name;
115 static XMLreader _notFound;
116 OutputChannel _outputChannel;
117protected:
118 std::map<std::string, std::string> _attributes;
119 std::vector<XMLreader*> _children;
120};
121
122// methods with template
123
124template <typename T, unsigned DIM>
125bool XMLreader::read(util::ADf<T,DIM>& value, bool verboseOn, bool exitIfMissing) const
126{
127 std::stringstream valueStr(_text);
128 T tmp = T();
129 if (!(valueStr >> tmp)) {
130// if ( _verboseOn ) {
131// clout << std::string("Error: cannot read value from XML element ") << _name << std::endl;
132// }
133 _output.printWarning(_name, "ADf vector", "", verboseOn, exitIfMissing);
134 return false;
135 }
136 value = util::ADf<T,DIM>(tmp);
137 return true;
138}
139
140template <typename T>
141bool XMLreader::read(std::vector<T>& values, bool verboseOn, bool exitIfMissing ) const
142{
143 std::stringstream multiValueStr(_text);
144 std::string word;
145 std::vector<T> tmp(values);
146 while (multiValueStr>>word) {
147 std::stringstream valueStr(word);
148 T value;
149 if (!(valueStr >> value)) {
150// if ( verboseOn ) {
151// clout << std::string("Error: cannot read value array from XML element ") << _name << std::endl;
152// }
153 _output.printWarning(_name, "std::vector", "", verboseOn, exitIfMissing);
154 return false;
155 }
156 tmp.push_back(value);
157 }
158 values.swap(tmp);
159 return true;
160}
161
162template <typename T>
163T XMLreader::get(bool verboseOn, bool exitIfMissing) const
164{
165 std::stringstream valueStr(_text);
166 T tmp = T();
167 if (!(valueStr >> tmp)) {
168// if ( verboseOn ) {
169// clout << "Error: cannot read value from XML element " << _name << std::endl;
170// }
171 _output.printWarning(_name, typeid(T).name(), "", verboseOn, exitIfMissing);
172 }
173 return tmp;
174}
175
176
177template<typename ParameterType>
178bool XMLreader::readOrWarn(std::string name_parameter_1,
179 std::string name_parameter_2, std::string name_parameter_3,
180 ParameterType& var, bool defaultAvailable, bool exitIfMissing, bool showWarning) const
181{
182 // deactivate default warnings and show default values instead
183 setWarningsOn(false);
184 if (name_parameter_3 == "") {
185 if (!(*this)[name_parameter_1][name_parameter_2].read<ParameterType>(var, false)) {
186 _output.parameterReading({name_parameter_1, name_parameter_2}, var, defaultAvailable, exitIfMissing, showWarning);
187 return false;
188 }
189 return true;
190 }
191 else{
192 if (!(*this)[name_parameter_1][name_parameter_2][name_parameter_3].read<ParameterType>(var, false)) {
193 _output.parameterReading({name_parameter_1, name_parameter_2, name_parameter_3}, var, defaultAvailable, exitIfMissing, showWarning);
194 return false;
195 }
196 return true;
197 }
198 // turn default warnings on again
199 setWarningsOn(true);
200}
201
202template<typename ParameterType>
203bool XMLreader::readOrWarn(std::string name_parameter_1,
204 std::string name_parameter_2, std::string name_parameter_3, std::string name_parameter_4,
205 ParameterType& var, bool defaultAvailable, bool exitIfMissing, bool showWarning) const
206{
207 // deactivate default warnings and show default values instead
208 setWarningsOn(false);
209 if (name_parameter_3 == "") {
210 if (!(*this)[name_parameter_1][name_parameter_2].read<ParameterType>(var, false)) {
211 _output.parameterReading({name_parameter_1, name_parameter_2}, var, defaultAvailable, exitIfMissing, showWarning);
212 return false;
213 }
214 return true;
215 }
216 else if(name_parameter_4 == ""){
217 if (!(*this)[name_parameter_1][name_parameter_2][name_parameter_3].read<ParameterType>(var, false)) {
218 _output.parameterReading({name_parameter_1, name_parameter_2, name_parameter_3}, var, defaultAvailable, exitIfMissing, showWarning);
219 return false;
220 }
221 return true;
222 }
223 else {
224 if (!(*this)[name_parameter_1][name_parameter_2][name_parameter_3][name_parameter_4].read<ParameterType>(var, false)) {
225 _output.parameterReading({name_parameter_1, name_parameter_2,name_parameter_3,name_parameter_4},
226 var, defaultAvailable, exitIfMissing, showWarning);
227 return false;
228 }
229 return true;
230 }
231 // turn default warnings on again
232 setWarningsOn(true);
233}
234
235XMLreader XMLreader::_notFound;
236
237XMLreader::XMLreader()
238{
239 _name = "XML node not found";
240 _warningsOn = true;
242}
243
244XMLreader::XMLreader( TiXmlNode* pParent, OutputChannel outputChannel) : _output(outputChannel)
245{
246 _outputChannel = outputChannel;
247 _warningsOn = true;
248
249 if (singleton::mpi().isMainProcessor()) {
250 mainProcessorIni(pParent);
251 }
252 else {
253 slaveProcessorIni();
254 }
255}
256
257XMLreader::XMLreader(const std::string& fName, OutputChannel outputChannel) : _output(outputChannel)
258{
259 _outputChannel = outputChannel;
260 _warningsOn = true;
261
262 TiXmlDocument* doc = nullptr;
263 int loadOK = false;
264#ifdef PARALLEL_MODE_MPI // parallel program execution
265 if (singleton::mpi().isMainProcessor()) {
266#endif
267 std::string docName = std::string(fName); // call copy constructor
268 doc = new TiXmlDocument(docName.c_str());
269 loadOK = doc->LoadFile();
270 _output.loadFile(loadOK, fName);
271#ifdef PARALLEL_MODE_MPI // parallel program execution
272 }
273 if (singleton::mpi().isMainProcessor()) {
274#endif
275 mainProcessorIni(doc);
276 delete doc;
277#ifdef PARALLEL_MODE_MPI // parallel program execution
278 }
279 else {
280 slaveProcessorIni();
281 }
282#endif
283}
284
286{
287 for (unsigned int iNode=0; iNode<_children.size(); ++iNode) {
288 delete _children[iNode];
289 }
290}
291
292void XMLreader::mainProcessorIni( TiXmlNode* pParent )
293{
294 assert (pParent->Type()==TiXmlNode::TINYXML_DOCUMENT || pParent->Type()==TiXmlNode::TINYXML_ELEMENT );
295 if (pParent->Type() == TiXmlNode::TINYXML_DOCUMENT) {
296 // ignore the surrounding PARAM-block
297 pParent = pParent->FirstChildElement();
298 }
299
300 _name = pParent->ValueStr();
301#ifdef PARALLEL_MODE_MPI // parallel program execution
302 singleton::mpi().bCast(&_name,1);
303#endif
304
305 TiXmlAttribute* attr = pParent->ToElement()->FirstAttribute();
306 while (attr != nullptr) {
307#ifdef PARALLEL_MODE_MPI // parallel program execution
308 int size = 0;
309 std::string* key = const_cast<std::string*>(&attr->NameTStr());
310 singleton::mpi().bCast(key, size);
311 std::string* value = const_cast<std::string*>(&attr->ValueStr());
312 singleton::mpi().bCast(value, size);
313#endif
314 _attributes[attr->NameTStr()] = attr->ValueStr();
315 attr = attr->Next();
316 }
317#ifdef PARALLEL_MODE_MPI // parallel program execution
318 std::string tmpstr = "";
319 int size = 0;
320 singleton::mpi().bCast(&tmpstr, size);
321 singleton::mpi().bCast(&tmpstr, size);
322#endif
323
324
325 TiXmlNode * pChild;
326 int type = 0;
327 for ( pChild = pParent->FirstChild(); pChild != nullptr; pChild = pChild->NextSibling()) {
328 type = pChild->Type();
329#ifdef PARALLEL_MODE_MPI // parallel program execution
330 singleton::mpi().bCast(&type, 1);
331#endif
332 if ( type==TiXmlNode::TINYXML_ELEMENT ) {
333 _children.push_back( new XMLreader( pChild , _outputChannel) );
334 }
335 else if ( type==TiXmlNode::TINYXML_TEXT ) {
336 _text = pChild->ToText()->ValueStr();
337#ifdef PARALLEL_MODE_MPI // parallel program execution
338 singleton::mpi().bCast(&_text,1);
339#endif
340 }
341 }
342 type = TiXmlNode::TINYXML_UNKNOWN;
343#ifdef PARALLEL_MODE_MPI // parallel program execution
344 singleton::mpi().bCast(&type, 1);
345#endif
346}
347
348void XMLreader::slaveProcessorIni()
349{
350#ifdef PARALLEL_MODE_MPI // parallel program execution
351
352 singleton::mpi().bCast(&_name,1);
353 std::string key = "";
354 std::string value = "";
355 int size = int();
356 do {
357 singleton::mpi().bCast(&key, size);
358 singleton::mpi().bCast(&value, size);
359 _attributes[key] = value;
360 }
361 while (key != "");
362#endif
363
364 int type=0;
365 do {
366#ifdef PARALLEL_MODE_MPI // parallel program execution
367 singleton::mpi().bCast(&type, 1);
368#endif
369 if ( type==TiXmlNode::TINYXML_ELEMENT ) {
370 _children.push_back( new XMLreader( nullptr, _outputChannel ) );
371 }
372 else if ( type==TiXmlNode::TINYXML_TEXT ) {
373#ifdef PARALLEL_MODE_MPI // parallel program execution
374 singleton::mpi().bCast(&_text,1);
375#endif
376 }
377 }
378 while (type != TiXmlNode::TINYXML_UNKNOWN);
379}
380
381XMLreader const& XMLreader::operator[] (std::string fName) const
382{
383 for (unsigned int iNode=0; iNode<_children.size(); ++iNode) {
384 if (_children[iNode]->_name == fName) {
385 return *_children[iNode];
386 }
387 }
388 _output.readValue(_warningsOn, _name, fName);
389 return _notFound;
390}
391
392std::vector<XMLreader*>::const_iterator XMLreader::begin() const
393{
394 return _children.begin();
395}
396
397std::vector<XMLreader*>::const_iterator XMLreader::end() const
398{
399 return _children.end();
400}
401
402std::string XMLreader::getName() const
403{
404 return _name;
405}
406
407std::string XMLreader::getText() const
408{
409 return _text;
410}
411
412void XMLreader::setWarningsOn(bool warnings) const
413{
414 _warningsOn = warnings;
415 for (unsigned int iNode=0; iNode<_children.size(); ++iNode) {
416 _children[iNode]->setWarningsOn(warnings);
417 }
418}
419
420// template specialization for T=bool
421template <>
422bool XMLreader::read<bool>(bool& value, bool verboseOn, bool exitIfMissing) const
423{
424 std::stringstream valueStr(_text);
425 std::string word;
426 valueStr >> word;
427 // Transform to lower-case, so that "true" and "false" are case-insensitive.
428 std::transform(word.begin(), word.end(), word.begin(), ::tolower);
429 if (!word.compare("true") || (word=="1")) {
430 value = true;
431 return true;
432 }
433 else if (!word.compare("false") || (word=="0")) {
434 value=false;
435 return true;
436 }
437 else {
438 if ( verboseOn ) {
439 std::stringstream ss;
440 ss << ( value ? "true" : "false" );
441 _output.printWarning(_name, "bool", ss.str(), verboseOn, exitIfMissing);
442 }
443 }
444 return false;
445}
446
447// template specialization for T=int
448template <>
449bool XMLreader::read<int>(int& value, bool verboseOn, bool exitIfMissing) const
450{
451 std::stringstream valueStr(_text);
452 int tmp = int();
453 if (!(valueStr >> tmp)) {
454 std::stringstream ss;
455 ss << value;
456 _output.printWarning(_name, "int", ss.str(), verboseOn, exitIfMissing);
457 return false;
458 }
459 value = tmp;
460 return true;
461}
462
463// template specialization for T=std::size_t
464template <>
465bool XMLreader::read<std::size_t>(std::size_t& value, bool verboseOn, bool exitIfMissing) const
466{
467 std::stringstream valueStr(_text);
468 std::size_t tmp = std::size_t();
469 if (!(valueStr >> tmp)) {
470 std::stringstream ss;
471 ss << value;
472 _output.printWarning(_name, "std::size_t", ss.str(), verboseOn, exitIfMissing);
473 return false;
474 }
475 value = tmp;
476 return true;
477}
478
479// template specialization for T=double
480template <>
481bool XMLreader::read<double>(double& value, bool verboseOn, bool exitIfMissing) const
482{
483 std::stringstream valueStr(_text);
484 double tmp = double();
485 if (!(valueStr >> tmp)) {
486 _output.printWarning(_name, "double", std::to_string(value), verboseOn, exitIfMissing);
487 return false;
488 }
489 value = tmp;
490 return true;
491}
492
493// template specialization for T=long double
494template <>
495bool XMLreader::read<long double>(long double& value, bool verboseOn, bool exitIfMissing) const
496{
497 std::stringstream valueStr(_text);
498 std::string tmp {};
499 if (!(valueStr >> tmp)) {
500 _output.printWarning(_name, "long double", std::to_string(value), verboseOn, exitIfMissing);
501 return false;
502 }
503 value = std::stold(tmp);
504 return true;
505}
506
507template <>
508bool XMLreader::read<float>(float& value, bool verboseOn, bool exitIfMissing) const
509{
510 std::stringstream valueStr(_text);
511 float tmp = float();
512 if (!(valueStr >> tmp)) {
513 std::stringstream ss;
514 ss << value;
515 _output.printWarning(_name, "float", ss.str(), verboseOn, exitIfMissing);
516 return false;
517 }
518 value = tmp;
519 return true;
520}
521
522template <>
523bool XMLreader::read<std::string>(std::string& entry, bool verboseOn, bool exitIfMissing) const
524{
525 if (_name == "XML node not found") {
526 return false;
527 }
528 std::stringstream valueStr(_text);
529 std::string tmp = std::string();
530 if (!(valueStr >> tmp)) {
531 std::stringstream ss;
532 ss << entry;
533 _output.printWarning(_name, "string", ss.str(), verboseOn, exitIfMissing);
534 return false;
535 }
536
537 entry = _text;
538 return true;
539}
540
541std::string XMLreader::getAttribute(const std::string& aName) const
542{
543 std::map<std::string, std::string>::const_iterator it = _attributes.find(aName);
544 if ( it == _attributes.end()) {
545 return "Attribute not found.";
546 }
547 return it->second;
548 //return attributes[aName];
549}
550
551
552} // namespace olb
553
554#endif // XML_IO_H
void loadFile(bool loadOK, std::string fName) const
void parameterReading(std::vector< std::string > parameters, ParameterType &var, bool defaultAvailable, bool exitIfMissing, bool showWarning) const
void printWarning(std::string name, std::string typeName, std::string value, bool verboseOn, bool exitIfMissing) const
print warning if verbose mode is on and exit, if exItMissing is true
void readValue(bool warningsOn, std::string name, std::string fName) const
std::string getAttribute(const std::string &aName) const
Definition xmlReader.h:541
std::vector< XMLreader * > _children
Definition xmlReader.h:119
std::vector< XMLreader * >::const_iterator begin() const
Returns an iterator.begin() of the child XMLreader This means an iterator to the next level on an XML...
Definition xmlReader.h:392
std::string getName() const
return the name of the element
Definition xmlReader.h:402
friend class olb::XMLreaderOutput
Definition xmlReader.h:50
T get(bool verboseOn=true, bool exitIfMissing=false) const
Definition xmlReader.h:163
XMLreaderOutput _output
handling all the output for the XMLreader
Definition xmlReader.h:106
bool readOrWarn(std::string name_parameter_1, std::string name_parameter_2, std::string name_parameter_3, ParameterType &var, bool defaultAvailable=true, bool exitIfMissing=false, bool showWarning=true) const
This wrapper function reads the given parameter from the "type_parameter" and "name_parameter_1" or "...
Definition xmlReader.h:178
void setWarningsOn(bool warnings) const
switch warnings on/off
Definition xmlReader.h:412
std::vector< XMLreader * >::const_iterator end() const
Returns an iterator.end() of the child XMLreader This means an iterator to the next level on an XML t...
Definition xmlReader.h:397
bool read(T &value, bool verboseOn=true, bool exitIfMissing=false) const
Prints out the XML structure read in, mostly for debugging purposes.
XMLreader const & operator[](std::string name) const
Definition xmlReader.h:381
std::map< std::string, std::string > _attributes
Definition xmlReader.h:118
std::string getText() const
return the text of the element
Definition xmlReader.h:407
XMLreader(TiXmlNode *pParent, OutputChannel outputChannel=OutputChannel::ERRCHANNEL)
Constructs a new XMLreader from another XMLreader.
Definition xmlReader.h:244
~XMLreader()
destructor
Definition xmlReader.h:285
void bCast(T *sendBuf, int sendCount, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Broadcast data from one processor to multiple processors.
Definition of a description of a algoritmic differentiation data type using the forward method.
Definition aDiff.h:64
Wrapper functions that simplify the use of MPI.
typename std::integral_constant< TYPE, VALUE >::type value
Identity type to wrap non-type template arguments.
Definition meta.h:96
MpiManager & mpi()
Top level namespace for all of OpenLB.
OutputChannel