Visual Servoing Platform  version 3.2.0 under development (2019-01-22)
testXmlParser.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Example which describes how to use the xml parser class.
33  *
34  * Author:
35  * Romain Tallonneau
36  *
37  *****************************************************************************/
38 
57 #include <visp3/core/vpConfig.h>
58 
59 #include <iostream>
60 #if defined(VISP_HAVE_XML2)
61 
62 #include <visp3/core/vpDebug.h>
63 #include <visp3/core/vpIoTools.h>
64 #include <visp3/core/vpXmlParser.h>
65 #include <visp3/io/vpParseArgv.h>
66 
67 #include <string>
68 
69 #ifndef DOXYGEN_SHOULD_SKIP_THIS
70 
71 /* --------------------------------------------------------------------------
72  */
73 /* CLASS EXAMPLE */
74 /* --------------------------------------------------------------------------
75  */
76 
82 class vpExampleDataParser : public vpXmlParser
83 {
84 protected:
85  double m_range;
86  int m_step;
87  int m_size_filter;
88  std::string m_name;
89 
90  typedef enum { config, range, step, size_filter, name } dataToParse;
91 
92 public:
93  vpExampleDataParser();
94  virtual ~vpExampleDataParser();
95 
96  // Data accessors.
97  double getRange() const { return m_range; }
98  int getStep() const { return m_step; }
99  int getSizeFilter() const { return m_size_filter; }
100  std::string getName() const { return m_name; }
101 
102  void setRange(const double _range) { m_range = _range; }
103  void setStep(const int _step) { m_step = _step; }
104  void setSizeFilter(const int _size_filter) { m_size_filter = _size_filter; }
105  void setName(const std::string &_name) { m_name = _name; }
106 
107 protected:
108  virtual void readMainClass(xmlDocPtr doc, xmlNodePtr node);
109  virtual void writeMainClass(xmlNodePtr node);
110 };
111 
118 vpExampleDataParser::vpExampleDataParser() : m_range(0.), m_step(0), m_size_filter(0), m_name("")
119 {
120  nodeMap["config"] = config;
121  nodeMap["range"] = range;
122  nodeMap["step"] = step;
123  nodeMap["size_filter"] = size_filter;
124  nodeMap["name"] = name;
125 }
126 
131 vpExampleDataParser::~vpExampleDataParser() {}
132 
141 void vpExampleDataParser::readMainClass(xmlDocPtr doc, xmlNodePtr node)
142 {
143  for (xmlNodePtr dataNode = node->xmlChildrenNode; dataNode != NULL; dataNode = dataNode->next) {
144  if (dataNode->type == XML_ELEMENT_NODE) {
145  std::map<std::string, int>::iterator iter_data = this->nodeMap.find((char *)dataNode->name);
146  if (iter_data != nodeMap.end()) {
147  switch (iter_data->second) {
148  case range:
149  this->m_range = xmlReadDoubleChild(doc, dataNode);
150  break;
151  case step:
152  this->m_step = xmlReadIntChild(doc, dataNode);
153  break;
154  case size_filter:
155  this->m_size_filter = xmlReadIntChild(doc, dataNode);
156  break;
157  case name: {
158  this->m_name = xmlReadStringChild(doc, dataNode);
159  } break;
160  default:
161  vpTRACE("unknown tag in readConfigNode : %d, %s", iter_data->second, (iter_data->first).c_str());
162  break;
163  }
164  }
165  }
166  }
167 }
168 
176 void vpExampleDataParser::writeMainClass(xmlNodePtr node)
177 {
178  xmlWriteDoubleChild(node, (const char *)"range", m_range);
179  xmlWriteIntChild(node, (const char *)"step", m_step);
180  xmlWriteIntChild(node, (const char *)"size_filter", m_size_filter);
181  xmlWriteCharChild(node, (const char *)"name", m_name.c_str());
182 }
183 
184 #endif // doxygen
185 
186 /* --------------------------------------------------------------------------
187  */
188 /* COMMAND LINE OPTIONS */
189 /* --------------------------------------------------------------------------
190  */
191 
192 // List of allowed command line options
193 #define GETOPTARGS "cdo:h"
194 
195 void usage(const char *name, const char *badparam, const std::string &opath, const std::string &user);
196 bool getOptions(int argc, const char **argv, std::string &opath, const std::string &user);
197 
208 void usage(const char *name, const char *badparam, const std::string &opath, const std::string &user)
209 {
210  fprintf(stdout, "\n\
211 Write and read data in a xml file.\n\
212  \n\
213 SYNOPSIS\n\
214  %s [-o <output image path>] [-h]\n", name);
215 
216  fprintf(stdout, "\n\
217 OPTIONS: Default\n\
218  -o <output data path> %s\n\
219  Set data output path.\n\
220  From this directory, creates the \"%s\"\n\
221  subdirectory depending on the username, where \n\
222  dataTestXml.xml file is written.\n\
223  \n\
224  -h\n\
225  Print the help.\n\n", opath.c_str(), user.c_str());
226 
227  if (badparam) {
228  fprintf(stderr, "ERROR: \n");
229  fprintf(stderr, "\nBad parameter [%s]\n", badparam);
230  }
231 }
232 
242 bool getOptions(int argc, const char **argv, std::string &opath, const std::string &user)
243 {
244  const char *optarg_;
245  int c;
246  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
247 
248  switch (c) {
249  case 'o':
250  opath = optarg_;
251  break;
252  case 'h':
253  usage(argv[0], NULL, opath, user);
254  return false;
255  break;
256 
257  case 'c':
258  case 'd':
259  break;
260 
261  default:
262  usage(argv[0], optarg_, opath, user);
263  return false;
264  break;
265  }
266  }
267 
268  if ((c == 1) || (c == -1)) {
269  // standalone param or error
270  usage(argv[0], NULL, opath, user);
271  std::cerr << "ERROR: " << std::endl;
272  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
273  return false;
274  }
275 
276  return true;
277 }
278 
279 /* --------------------------------------------------------------------------
280  */
281 /* MAIN FUNCTION */
282 /* --------------------------------------------------------------------------
283  */
284 
285 int main(int argc, const char **argv)
286 {
287  try {
288  std::string opt_opath;
289  std::string opath;
290  std::string filename;
291  std::string username;
292 
293  std::cout << "-------------------------------------------------------" << std::endl;
294  std::cout << " testXmlParser.cpp" << std::endl << std::endl;
295  std::cout << " writing and readind data using a xml parser" << std::endl;
296  std::cout << "-------------------------------------------------------" << std::endl;
297  std::cout << std::endl;
298 
299 // Set the default output path
300 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
301  opt_opath = "/tmp";
302 #elif defined(_WIN32)
303  opt_opath = "C:\\temp";
304 #endif
305 
306  // Get the user login name
307  vpIoTools::getUserName(username);
308 
309  // Read the command line options
310  if (getOptions(argc, argv, opt_opath, username) == false) {
311  exit(-1);
312  }
313 
314  // Get the option values
315  if (!opt_opath.empty())
316  opath = opt_opath;
317 
318  // Append to the output path string, the login name of the user
319  std::string dirname = vpIoTools::createFilePath(opath, username);
320 
321  // Test if the output path exist. If no try to create it
322  if (vpIoTools::checkDirectory(dirname) == false) {
323  try {
324  // Create the dirname
325  vpIoTools::makeDirectory(dirname);
326  } catch (...) {
327  usage(argv[0], NULL, opath, username);
328  std::cerr << std::endl << "ERROR:" << std::endl;
329  std::cerr << " Cannot create " << dirname << std::endl;
330  std::cerr << " Check your -o " << opath << " option " << std::endl;
331  exit(-1);
332  }
333  }
334 
335  filename = dirname + vpIoTools::path("/") + "dataTestXml.xml";
336 
337  // Write data using a parser.
338  {
339  vpExampleDataParser parser1;
340 
341  // Acquire data from measurments or tests.
342  parser1.setRange(3.5);
343  parser1.setStep(2);
344  parser1.setSizeFilter(5);
345  parser1.setName("cube");
346 
347  std::cout << "Write data to " << filename << std::endl;
348  parser1.save(filename);
349  }
350 
351  // Read data using another parser.
352  {
353  vpExampleDataParser parser2;
354 
355  parser2.parse(filename);
356 
357  std::cout << "Read from " << filename << std::endl;
358  std::cout << "Range : " << parser2.getRange() << std::endl;
359  std::cout << "Step : " << parser2.getStep() << std::endl;
360  std::cout << "Filter size : " << parser2.getSizeFilter() << std::endl;
361  std::cout << "name : " << parser2.getName() << std::endl;
362  }
363 
364  // Clean up memory allocated by the xml library
366  return 0;
367  } catch (const vpException &e) {
368  std::cout << "Catch an exception: " << e << std::endl;
369  return 1;
370  }
371 }
372 
373 #else
374 
375 int main()
376 {
377  std::cout << "Xml parser requires libxml2." << std::endl;
378  return 0;
379 }
380 #endif
static bool checkDirectory(const char *dirname)
Definition: vpIoTools.cpp:467
error that can be emited by ViSP classes.
Definition: vpException.h:71
static std::string path(const char *pathname)
Definition: vpIoTools.cpp:941
virtual void writeMainClass(xmlNodePtr node)=0
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
This class intends to simplify the creation of xml parser based on the libxml2 third party library...
Definition: vpXmlParser.h:177
static void makeDirectory(const char *dirname)
Definition: vpIoTools.cpp:597
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1541
#define vpTRACE
Definition: vpDebug.h:416
static std::string getUserName()
Definition: vpIoTools.cpp:298
virtual void readMainClass(xmlDocPtr doc, xmlNodePtr node)=0
static void cleanup()
Definition: vpXmlParser.h:310