Bridge++  Version 1.4.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
parameterManager_XML.cpp
Go to the documentation of this file.
1 
14 #include "parameterManager_XML.h"
15 
16 #include "Tools/evalexpr.h"
17 
18 #include <fstream>
19 #include <sstream>
20 #include <map>
21 #include <vector>
22 
23 #include "tinyxml2.h"
24 using namespace tinyxml2;
25 
26 #include "IO/bridgeIO.h"
27 using Bridge::vout;
28 
29 using std::string;
30 using std::vector;
31 using std::map;
32 
33 const std::string ParameterManager_XML::class_name = "ParameterManager_XML";
34 
35 //====================================================================
37 {
38  public:
39  static const string class_name;
40 
41  public:
42  int parse(const char *buf, Parameters& params);
43 
45  : m_vl(CommonParameters::Vlevel()) {}
46 
47  private:
48 
49  int store_map_data(const XMLElement *, Parameters&);
50  int store_vector_data(const XMLElement *, vector<string>&);
51 
52  void traverse(const XMLElement *, const string& indent = "") const;
53 
54  protected:
56 };
57 
58 //--------------------------------------------------------------------
59 const string Parser_tinyxml::class_name = "ParameterManager_XML::Parser_tinyxml";
60 
61 //--------------------------------------------------------------------
62 int Parser_tinyxml::parse(const char *buf, Parameters& params)
63 {
64  if (!buf) return EXIT_FAILURE;
65 
66  XMLDocument doc;
67 
68  XMLError err = doc.Parse(buf);
69 
70  if (err != XML_NO_ERROR) {
71  vout.crucial(m_vl, "Error at %s: parse failed: %s\n", class_name.c_str(), doc.ErrorName());
72 
73  const char *err_str1 = doc.GetErrorStr1();
74  if (err_str1) {
75  vout.crucial(m_vl, " %s\n", err_str1);
76  }
77  const char *err_str2 = doc.GetErrorStr2();
78  if (err_str2) {
79  vout.crucial(m_vl, " %s\n", err_str2);
80  }
81 
82  exit(EXIT_FAILURE);
83  }
84 
85  XMLElement *root = doc.FirstChildElement("Parameters");
86  if (!root) {
87  vout.crucial(m_vl, "Error at %s: tag \"Parameters\" not found.\n", class_name.c_str());
88  exit(EXIT_FAILURE);
89  }
90 
91  // traverse(root); // for debug
92 
93  for (const XMLElement *e = root->FirstChildElement(); e; e = e->NextSiblingElement()) {
94  int retv = store_map_data(e, params);
95 
96  if (retv != EXIT_SUCCESS) {
97  vout.crucial(m_vl, "Error at %s: parse failed.\n", class_name.c_str());
98  return EXIT_FAILURE;
99  }
100  }
101 
102  return EXIT_SUCCESS;
103 }
104 
105 
106 //--------------------------------------------------------------------
107 int Parser_tinyxml::store_vector_data(const XMLElement *elem, vector<string>& v)
108 {
109  if (!elem) return EXIT_FAILURE;
110 
111  const XMLElement *ee = elem->FirstChildElement();
112  if (!ee) return EXIT_FAILURE;
113 
114  map<int, string> mm;
115  int max_index = 0;
116 
117  if (strcmp(ee->Name(), "value") == 0) { // <value id="n">item</value>
118  int count = 0;
119 
120  for (const XMLElement *e = elem->FirstChildElement(); e; e = e->NextSiblingElement()) {
121  int id = 0;
122 
123  if (e->QueryIntAttribute("id", &id) == XML_SUCCESS) {
124  --id; // id = 1, 2, 3, ...
125  } else {
126  id = count;
127  }
128 
129  if (id < 0) {
130  fprintf(stderr, "Error. inappropriate id\n");
131  return EXIT_FAILURE;
132  }
133 
134  if (id > max_index) max_index = id;
135 
136  mm[id] = e->GetText();
137  ++count;
138  }
139  } else { // <x>item</x> <y>item</y> ...
140  for (const XMLElement *e = elem->FirstChildElement(); e; e = e->NextSiblingElement()) {
141  int id = 0;
142 
143  string tag = e->Name();
144 
145  if (tag == "x") {
146  id = 0;
147  } else if (tag == "y") {
148  id = 1;
149  } else if (tag == "z") {
150  id = 2;
151  } else if (tag == "t") {
152  id = 3;
153  } else if (tag == "w") {
154  id = 4;
155  } else {
156  fprintf(stderr, "unknown tag.\n");
157  return EXIT_FAILURE;
158  }
159 
160  if (id > max_index) max_index = id;
161 
162  mm[id] = e->GetText();
163  }
164  }
165 
166  vector<string> vv(max_index + 1);
167 
168  for (map<int, string>::const_iterator p = mm.begin(); p != mm.end(); ++p) {
169  vv[p->first] = p->second;
170  }
171 
172  v = vv;
173 
174  return EXIT_SUCCESS;
175 }
176 
177 
178 //--------------------------------------------------------------------
180 {
181  if (!elem) return EXIT_FAILURE;
182 
183  const char *elem_name = elem->Name();
184  const char *elem_value = elem->GetText();
185 
186  if (elem_value != NULL) { /* assume leaf node */
187  // store to scalar map
188  params.set_string(elem_name, elem_value);
189 
190  return EXIT_SUCCESS;
191  }
192 
193  const char *elem_attr = elem->Attribute("type");
194 
195  if (elem_attr && (strcmp(elem_attr, "sequence") == 0)) { /* sequence */
196  vector<string> v;
197  int retv = store_vector_data(elem, v);
198 
199  if (retv == EXIT_SUCCESS) {
200  // store to sequence map
201  params.set_string_vector(elem_name, v);
202  }
203 
204  return retv;
205  }
206 
207  Parameters pp;
208 
209  for (const XMLElement *e = elem->FirstChildElement(); e; e = e->NextSiblingElement()) {
210  int retv = store_map_data(e, pp);
211 
212  if (retv != EXIT_SUCCESS) {
213  return EXIT_FAILURE;
214  }
215  }
216 
217  // store to map map
218  params.set_Parameters(elem_name, pp);
219 
220  return EXIT_SUCCESS;
221 }
222 
223 
224 //--------------------------------------------------------------------
225 void Parser_tinyxml::traverse(const XMLElement *elem, const string& indent) const
226 {
227  if (!elem) return;
228 
229  const char *elem_name = elem->Name();
230  const char *elem_value = elem->GetText();
231 
232  if (elem_value != NULL) { /* assume leaf node */
233  vout.general(m_vl, "%sElementName = %s, value = %s\n", indent.c_str(), elem_name, elem_value);
234  return;
235  } else {
236  vout.general(m_vl, "%sElementName = %s\n", indent.c_str(), elem_name);
237 
238  const char *elem_attr = elem->Attribute("type");
239  if (elem_attr && (strcmp(elem_attr, "sequence") == 0)) {
240  vout.general(m_vl, "%s- is a sequence.\n", indent.c_str());
241  }
242 
243  for (const XMLElement *e = elem->FirstChildElement(); e; e = e->NextSiblingElement()) {
244  traverse(e, indent + " ");
245  }
246  }
247 }
248 
249 
250 //--------------------------------------------------------------------
251 
252 //====================================================================
253 void ParameterManager_XML::read_params(const std::string& params_file, Parameters& params)
254 {
255  const int io_node = 0; // node id for file i/o.
256 
257  int filesize = 0;
258  char *buf = 0;
259 
260  if (Communicator::nodeid() == io_node) {
261  // load and distribute
262  std::ifstream fin(params_file.c_str());
263  if (!fin) {
264  vout.crucial(m_vl, "Error at %s: unable to read parameter file: %s.\n", class_name.c_str(), params_file.c_str());
265 
267  }
268 
269  fin.seekg(0, std::ios::end);
270  filesize = fin.tellg();
271  fin.seekg(0, std::ios::beg);
272 
273  int padding = 8 - (filesize % 8);
274 
275  vout.paranoiac(m_vl, "%s::%s: filesize = %d, padding = %d\n", class_name.c_str(), __func__, filesize, padding);
276 
277  filesize += padding;
278 
279  Communicator::broadcast(1, &filesize, io_node);
280 
281  buf = new char [filesize];
282  memset(buf, 0, filesize);
283 
284  fin.read(buf, filesize - padding);
285 
286  Communicator::Base::broadcast(filesize, buf, io_node);
287  } else {
288  // receive from io_node
289 
290  Communicator::broadcast(1, &filesize, io_node);
291 
292  buf = new char [filesize];
293  memset(buf, 0, filesize);
294 
295  Communicator::Base::broadcast(filesize, buf, io_node);
296  }
297 
298  Parser_tinyxml().parse(buf, params);
299 
300  // params.dump(); // for debug
301 
302  delete [] buf;
303 }
304 
305 
306 //====================================================================
307 //============================================================END=====
void set_Parameters(const string &key, const Parameters &value)
Definition: parameters.cpp:46
BridgeIO vout
Definition: bridgeIO.cpp:495
static void abort()
terminate communicator
XMLError Parse(const char *xml, size_t nBytes=(size_t)(-1))
Definition: tinyxml2.cpp:1861
void general(const char *format,...)
Definition: bridgeIO.cpp:195
int store_vector_data(const XMLElement *, vector< string > &)
static int broadcast(size_t size, void *data, int sender)
Class for parameters.
Definition: parameters.h:46
void traverse(const XMLElement *, const string &indent="") const
static const string class_name
const char * GetErrorStr2() const
Return a possibly helpful secondary diagnostic location or string.
Definition: tinyxml2.h:1719
void set_string(const string &key, const string &value)
Definition: parameters.cpp:34
Bridge::VerboseLevel m_vl
const XMLElement * FirstChildElement(const char *value=0) const
Definition: tinyxml2.cpp:770
const char * Attribute(const char *name, const char *value=0) const
Definition: tinyxml2.cpp:1287
int parse(const char *buf, Parameters &params)
const char * GetText() const
Definition: tinyxml2.cpp:1300
Common parameter class: provides parameters as singleton.
void paranoiac(const char *format,...)
Definition: bridgeIO.cpp:229
static const std::string class_name
void crucial(const char *format,...)
Definition: bridgeIO.cpp:178
const char * GetErrorStr1() const
Return a possibly helpful diagnostic location or string.
Definition: tinyxml2.h:1715
int store_map_data(const XMLElement *, Parameters &)
const XMLElement * NextSiblingElement(const char *value=0) const
Get the next (right) sibling element of this node, with an optionally supplied name.
Definition: tinyxml2.cpp:798
VerboseLevel
Definition: bridgeIO.h:42
static int broadcast(int count, double *data, int sender)
broadcast array of double from sender.
void read_params(const std::string &params_file, Parameters &params)
read parameters from file.
static int nodeid()
alternative name for self().
Definition: communicator.h:92
const char * ErrorName() const
Definition: tinyxml2.cpp:1909
const char * Name() const
Get the name of an element (which is the Value() of the node.)
Definition: tinyxml2.h:1181
void set_string_vector(const string &key, const vector< string > &value)
Definition: parameters.cpp:43