YARP
Yet Another Robot Platform
xmlresloader.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
7 #include <yarp/conf/filesystem.h>
8 #include <yarp/manager/utility.h>
9 #include <dirent.h>
12 
13 #include <algorithm>
14 #include <cctype>
15 #include <string>
16 #include <fstream>
18 #include <tinyxml.h>
19 
20 
21 using namespace yarp::manager;
22 
23 
24 XmlResLoader::XmlResLoader(const char* szPath, const char* szName)
25 {
26  parser = new(TextParser);
27  if(strlen(szPath))
28  {
29  const std::string directorySeparator{yarp::conf::filesystem::preferred_separator};
30  strPath = szPath;
31  if ((strPath.rfind(directorySeparator) == std::string::npos) || (strPath.rfind(directorySeparator) != strPath.size() - 1)) {
32  strPath = strPath + std::string(directorySeparator);
33  }
34  }
35 
36  if (szName) {
37  strName = szName;
38  }
39 }
40 
44 XmlResLoader::XmlResLoader(const char* szFileName)
45 {
46  parser = new(TextParser);
47  if (szFileName) {
48  strFileName = szFileName;
49  }
50 }
51 
52 
53 
55 {
56  if(parser)
57  {
58  delete parser;
59  }
60 }
61 
62 
64 {
65  fileNames.clear();
67 
71  if(!strFileName.empty())
72  {
73  fileNames.push_back(strFileName);
74  return true;
75  }
76 
77  if(strPath.empty())
78  {
79  logger->addError("No module path is introduced.");
80  return false;
81  }
82 
83  DIR *dir;
84  struct dirent *entry;
85  if ((dir = opendir(strPath.c_str())) == nullptr)
86  {
87  OSTRINGSTREAM err;
88  err<<"Cannot access "<<strPath;
89  logger->addError(err);
90  return false;
91  }
92 
93  /* we need to load all xml files */
94  while((entry = readdir(dir)))
95  {
96  std::string name = entry->d_name;
97  if(name.size() > 3)
98  {
99  std::string ext = name.substr(name.size()-3,3);
100  if (compareString(ext.c_str(), "xml")) {
101  fileNames.push_back(strPath + name);
102  }
103  }
104  }
105  closedir(dir);
106 
107  /*
108  if(fileNames.empty())
109  {
110  OSTRINGSTREAM err;
111  err<<"No xml resource file found in "<<strPath;
112  logger->addWarning(err);
113  //return true;
114  }
115  */
116  return true;
117 }
118 
119 
121 {
122  fini();
123  init();
124 }
125 
126 
128 {
129  fileNames.clear();
130 }
131 
132 
134 {
135  if(strName.empty())
136  {
137  if(computers.size())
138  {
139  dummyComputer = computers.back();
140  computers.pop_back();
141  return &dummyComputer;
142  }
143  else
144  {
145  bool ret = false;
146  do
147  {
148  if (fileNames.empty()) {
149  return nullptr;
150  }
151 
152  std::string fname = fileNames.back();
153  fileNames.pop_back();
154  ret = parsXml(fname.c_str());
155  } while(!ret);
156 
157  dummyComputer = computers.back();
158  computers.pop_back();
159  return &dummyComputer;
160  }
161  }
162  else
163  {
167  std::vector<std::string>::iterator itr;
168  for(itr=fileNames.begin(); itr<fileNames.end(); itr++)
169  {
170  if(parsXml((*itr).c_str()))
171  {
172  for (auto& computer : computers) {
173  if (std::string(computer.getName()) == strName) {
174  return &computer;
175  }
176  }
177  }
178  }
179  }
180  return nullptr;
181 }
182 
183 
184 
185 bool XmlResLoader::parsXml(const char* szFile)
186 {
187  computers.clear();
188 
190 
191  TiXmlDocument doc(szFile);
192  if(!doc.LoadFile())
193  {
194  OSTRINGSTREAM err;
195  err<<"Syntax error while loading "<<szFile<<" at line "\
196  <<doc.ErrorRow()<<": ";
197  err<<doc.ErrorDesc();
198  logger->addError(err);
199  return false;
200  }
201  /* retrieving root module */
202  TiXmlElement *root = doc.RootElement();
203  if(!root)
204  {
205  OSTRINGSTREAM err;
206  err<<"Syntax error while loading "<<szFile<<" . ";
207  err<<"No root element.";
208  logger->addError(err);
209  return false;
210  }
211 
212 
213 
214  if(!compareString(root->Value(), "resources"))
215  {
216  /*
217  OSTRINGSTREAM msg;
218  msg<<szFile<<" is not a resource descriptor file.";
219  logger->addWarning(msg);
220  */
221  return false;
222  }
223 
224  for(TiXmlElement* var = root->FirstChildElement("var"); var; var = var->NextSiblingElement())
225  {
226  if(var->Attribute("name") && var->GetText())
227  {
228  parser->addVariable(var->Attribute("name"), var->GetText());
229  }
230  }
231 
232  /* retrieving all computers descriptions */
233  for(TiXmlElement* restag = root->FirstChildElement();
234  restag; restag = restag->NextSiblingElement())
235  {
236  /* retrieving a computer resource */
237  if(compareString(restag->Value(), "computer"))
238  {
239  Computer computer;
240  computer.setXmlFile(szFile);
241 
242  for(TiXmlElement* comptag = restag->FirstChildElement();
243  comptag; comptag = comptag->NextSiblingElement())
244  {
245  /* retrieving name */
246  if (compareString(comptag->Value(), "name")) {
247  computer.setName(parser->parseText(comptag->GetText()).c_str());
248  }
249 
250  /* retrieving description */
251  if (compareString(comptag->Value(), "description")) {
252  computer.setDescription(parser->parseText(comptag->GetText()).c_str());
253  }
254 
255  /* retrieving disablility */
256  if(compareString(comptag->Value(), "disable"))
257  {
258  if (compareString(parser->parseText(comptag->GetText()).c_str(), "yes")) {
259  computer.setDisable(true);
260  }
261  }
262 
263  // platform
264  if(compareString(comptag->Value(), "platform"))
265  {
266  Platform os;
267  TiXmlElement* element;
268  if ((element = (TiXmlElement*)comptag->FirstChild("name"))) {
269  os.setName(parser->parseText(element->GetText()).c_str());
270  } else {
271  OSTRINGSTREAM war;
272  war<<"Platform from "<<szFile<<" at line "\
273  <<comptag->Row()<<" has no name.";
274  logger->addWarning(war);
275  }
276 
277  if ((element = (TiXmlElement*)comptag->FirstChild("distribution"))) {
278  os.setDistribution(parser->parseText(element->GetText()).c_str());
279  }
280 
281  if ((element = (TiXmlElement*)comptag->FirstChild("release"))) {
282  os.setRelease(parser->parseText(element->GetText()).c_str());
283  }
284 
285  computer.setPlatform(os);
286  } // end of platform tag
287 
288  // memory
289  if(compareString(comptag->Value(), "memory"))
290  {
291  Memory mem;
292  TiXmlElement* element;
293  if ((element = (TiXmlElement*)comptag->FirstChild("total_space"))) {
294  mem.setTotalSpace((Capacity)atol(parser->parseText(element->GetText()).c_str()));
295  }
296  computer.setMemory(mem);
297  } // end of memory tag
298 
299  // storage
300  if(compareString(comptag->Value(), "storage"))
301  {
302  Storage stg;
303  TiXmlElement* element;
304  if ((element = (TiXmlElement*)comptag->FirstChild("total_space"))) {
305  stg.setTotalSpace((Capacity)atol(parser->parseText(element->GetText()).c_str()));
306  }
307  computer.setStorage(stg);
308  } // end of storage tag
309 
310  // processor
311  if(compareString(comptag->Value(), "processor"))
312  {
313  Processor proc;
314  TiXmlElement* element;
315  if ((element = (TiXmlElement*)comptag->FirstChild("architecture"))) {
316  proc.setArchitecture(parser->parseText(element->GetText()).c_str());
317  }
318  if ((element = (TiXmlElement*)comptag->FirstChild("model"))) {
319  proc.setModel(parser->parseText(element->GetText()).c_str());
320  }
321  if ((element = (TiXmlElement*)comptag->FirstChild("cores"))) {
322  proc.setCores((size_t)atoi(parser->parseText(element->GetText()).c_str()));
323  }
324  if ((element = (TiXmlElement*)comptag->FirstChild("frequency"))) {
325  proc.setFrequency(atof(parser->parseText(element->GetText()).c_str()));
326  }
327  computer.setProcessor(proc);
328  } // end of processor tag
329 
330  // network
331  if(compareString(comptag->Value(), "network"))
332  {
333  Network net;
334  TiXmlElement* element;
335  if ((element = (TiXmlElement*)comptag->FirstChild("ip4"))) {
336  net.setIP4(parser->parseText(element->GetText()).c_str());
337  }
338  if ((element = (TiXmlElement*)comptag->FirstChild("ip6"))) {
339  net.setIP6(parser->parseText(element->GetText()).c_str());
340  }
341  if ((element = (TiXmlElement*)comptag->FirstChild("mac"))) {
342  net.setMAC(parser->parseText(element->GetText()).c_str());
343  }
344  computer.setNetwork(net);
345  } // end of network tag
346 
347 
348  // gpu
349  if(compareString(comptag->Value(), "gpu"))
350  {
351  GPU gpu;
352  TiXmlElement* element;
353  if ((element = (TiXmlElement*)comptag->FirstChild("name"))) {
354  gpu.setName(parser->parseText(element->GetText()).c_str());
355  }
356  if ((element = (TiXmlElement*)comptag->FirstChild("capability"))) {
357  gpu.setCompCompatibility(parser->parseText(element->GetText()).c_str());
358  }
359  if ((element = (TiXmlElement*)comptag->FirstChild("cores"))) {
360  gpu.setCores((size_t)atoi(parser->parseText(element->GetText()).c_str()));
361  }
362  if ((element = (TiXmlElement*)comptag->FirstChild("frequency"))) {
363  gpu.setFrequency(atof(parser->parseText(element->GetText()).c_str()));
364  }
365  if ((element = (TiXmlElement*)comptag->FirstChild("register_block"))) {
366  gpu.setResgisterPerBlock((size_t)atoi(parser->parseText(element->GetText()).c_str()));
367  }
368  if ((element = (TiXmlElement*)comptag->FirstChild("thread_block"))) {
369  gpu.setThreadPerBlock((size_t)atoi(parser->parseText(element->GetText()).c_str()));
370  }
371  if((element = (TiXmlElement*) comptag->FirstChild("overlap")))
372  {
373  if (compareString(parser->parseText(element->GetText()).c_str(), "yes")) {
374  gpu.setOverlap(true);
375  } else {
376  gpu.setOverlap(false);
377  }
378  }
379 
380  // global memory
381  if(comptag->FirstChild("global_memory"))
382  {
383  TiXmlElement* element;
384  element = (TiXmlElement*) comptag->FirstChild("global_memory");
385  if ((element = (TiXmlElement*)element->FirstChild("total_space"))) {
386  gpu.setGlobalMemory((Capacity)atol(parser->parseText(element->GetText()).c_str()));
387  }
388  } // end of global memory tag
389 
390  // shared memory
391  if(comptag->FirstChild("shared_memory"))
392  {
393  TiXmlElement* element;
394  element = (TiXmlElement*) comptag->FirstChild("shared_memory");
395  if ((element = (TiXmlElement*)element->FirstChild("total_space"))) {
396  gpu.setSharedMemory((Capacity)atol(parser->parseText(element->GetText()).c_str()));
397  }
398  } // end of shared memory tag
399 
400  // constant memory
401  if(comptag->FirstChild("constant_memory"))
402  {
403  TiXmlElement* element;
404  element = (TiXmlElement*) comptag->FirstChild("constant_memory");
405  if ((element = (TiXmlElement*)element->FirstChild("total_space"))) {
406  gpu.setConstantMemory((Capacity)atol(parser->parseText(element->GetText()).c_str()));
407  }
408  } // end of shared memory tag
409 
410  computer.addPeripheral(gpu);
411  } // end of gpu tag
412  } // end of computer loop
413 
414  computers.push_back(computer);
415  } // end of if computer
416  } // end of resources
417  return true;
418 }
bool ret
void setProcessor(Processor &proc)
Definition: primresource.h:184
void setNetwork(Network &net)
Definition: primresource.h:185
bool addPeripheral(GenericResource &res)
void setPlatform(Platform &os)
Definition: primresource.h:186
void setStorage(Storage &stg)
Definition: primresource.h:183
void setMemory(Memory &mem)
Definition: primresource.h:182
Singleton class ErrorLogger.
Definition: utility.h:57
void addError(const char *szError)
Definition: utility.cpp:118
void addWarning(const char *szWarning)
Definition: utility.cpp:104
static ErrorLogger * Instance()
Singleton class ErrorLogger.
Definition: utility.cpp:98
void setFrequency(double f)
void setThreadPerBlock(size_t val)
void setOverlap(bool flag)
void setCompCompatibility(const char *cap)
void setConstantMemory(Capacity c)
void setSharedMemory(Capacity c)
void setCores(size_t n)
void setResgisterPerBlock(size_t val)
void setGlobalMemory(Capacity c)
void setName(const char *szName)
Definition: resource.h:28
void setXmlFile(const char *szFilename)
Definition: resource.h:36
void setDescription(const char *szDesc)
Definition: resource.h:30
void setDisable(bool flag)
Definition: resource.h:25
void setTotalSpace(Capacity c)
Definition: primresource.h:32
void setIP4(const char *ip)
Definition: primresource.h:81
void setIP6(const char *ip)
Definition: primresource.h:86
void setMAC(const char *mac)
Definition: primresource.h:91
void setDistribution(const char *str)
Definition: logicresource.h:28
void setRelease(const char *str)
Definition: logicresource.h:29
void setArchitecture(const char *arch)
Definition: primresource.h:128
void setCores(size_t n)
Definition: primresource.h:138
void setModel(const char *model)
Definition: primresource.h:133
void setFrequency(double f)
Definition: primresource.h:140
void setTotalSpace(Capacity c)
Definition: primresource.h:57
bool addVariable(const std::string &key, const std::string &value)
Definition: textparser.h:30
std::string parseText(const char *element)
Definition: textparser.h:44
GenericResource * getNextResource() override
XmlResLoader(const char *szFileName)
load only one module indicated by its xml file name
static constexpr value_type preferred_separator
Definition: filesystem.h:23
bool compareString(const char *szFirst, const char *szSecond)
Definition: utility.cpp:310
size_t Capacity
Definition: primresource.h:19
std::stringstream OSTRINGSTREAM
Definition: utility.h:49