ViSP  2.9.0
vpXmlParser.cpp
1 /****************************************************************************
2  *
3  * $Id: vpXmlParser.cpp 4632 2014-02-03 17:06:40Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Tool to automatise the creation of xml parser based on the libXML2
36  *
37  * Authors:
38  * Romain Tallonneau
39  *
40  *****************************************************************************/
41 
42 #include <visp/vpXmlParser.h>
43 #include <visp/vpConfig.h>
44 
45 #ifdef VISP_HAVE_XML2
46 
47 #include <visp/vpException.h>
48 #include <visp/vpDebug.h>
49 #include <libxml/parser.h>
50 
51 #include <string>
52 #include <sstream>
53 #include <iomanip>
54 #include <typeinfo>
55 
61 vpXmlParser::vpXmlParser() : nodeMap(), main_tag("config")
62 {
63 }
64 
80 {
81  //xmlCleanupParser();
82 }
83 
90  : nodeMap(), main_tag("config")
91 {
92  main_tag = _twin.main_tag;
93  nodeMap = _twin.nodeMap;
94 }
95 
96 /* utilities functions to read/write data from an xml document */
97 
109 char*
110 vpXmlParser::xmlReadCharChild (xmlDocPtr doc, xmlNodePtr node)
111 {
112  if(node ->xmlChildrenNode == NULL){
113  std::string errorMsg = "Empty node " + std::string((char*)node->name) + ", cannot read char*";
114  std::cerr << errorMsg << std::endl;
115  throw vpException(vpException::fatalError, errorMsg);
116  }
117  return (char *) xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
118 }
119 
130 std::string
131 vpXmlParser::xmlReadStringChild (xmlDocPtr doc, xmlNodePtr node)
132 {
133  if(node ->xmlChildrenNode == NULL){
134  std::string errorMsg = "Empty node " + std::string((char*)node->name) + ", cannot read std::string";
135  std::cerr << errorMsg << std::endl;
136  throw vpException(vpException::fatalError, errorMsg);
137  }
138  char* dataCh = (char*)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
139  std::string dataStr = dataCh;
140  xmlFree(dataCh);
141  return dataStr;
142 }
143 
154 int
155 vpXmlParser::xmlReadIntChild (xmlDocPtr doc, xmlNodePtr node)
156 {
157  if(node ->xmlChildrenNode == NULL){
158  std::string errorMsg = "Empty node " + std::string((char*)node->name) + ", cannot read int";
159  std::cerr << errorMsg << std::endl;
160  throw vpException(vpException::fatalError, errorMsg);
161  }
162  char * val_char;
163  char * control_convert;
164  int val_int;
165 
166  val_char = (char *) xmlNodeListGetString(doc, node ->xmlChildrenNode, 1);
167  val_int = strtol ((char *)val_char, &control_convert, 10);
168 
169  if (val_char == control_convert){
170  xmlFree((xmlChar*) val_char);
171  throw vpException(vpException::ioError, "cannot parse entry to int");
172  }
173  xmlFree((xmlChar*) val_char);
174 
175  return val_int;
176 }
177 
188 unsigned int
189 vpXmlParser::xmlReadUnsignedIntChild (xmlDocPtr doc, xmlNodePtr node)
190 {
191  if(node ->xmlChildrenNode == NULL){
192  std::string errorMsg = "Empty node " + std::string((char*)node->name) + ", cannot read unsigned int";
193  std::cerr << errorMsg << std::endl;
194  throw vpException(vpException::fatalError, errorMsg);
195  }
196  char * val_char;
197  char * control_convert;
198  unsigned int val_uint;
199 
200  val_char = (char *) xmlNodeListGetString(doc, node ->xmlChildrenNode, 1);
201  val_uint = strtoul ((char *)val_char, &control_convert, 10);
202 
203  if (val_char == control_convert){
204  xmlFree((xmlChar*) val_char);
205  throw vpException(vpException::ioError, "cannot parse entry to int");
206  }
207  xmlFree((xmlChar*) val_char);
208 
209  return val_uint;
210 }
211 
212 
223 double
224 vpXmlParser::xmlReadDoubleChild (xmlDocPtr doc, xmlNodePtr node)
225 {
226  if(node ->xmlChildrenNode == NULL){
227  std::string errorMsg = "Empty node " + std::string((char*)node->name) + ", cannot read double";
228  std::cerr << errorMsg << std::endl;
229  throw vpException(vpException::fatalError, errorMsg);
230  }
231  char * val_char;
232  char * control_convert;
233  double val_double;
234 
235  val_char = (char *) xmlNodeListGetString(doc, node ->xmlChildrenNode, 1);
236  val_double = strtod ((char *)val_char, &control_convert);
237 
238  if (val_char == control_convert){
239  xmlFree((xmlChar*) val_char);
240  throw vpException(vpException::ioError, "cannot parse entry to double");
241  }
242  xmlFree((xmlChar*) val_char);
243  return val_double;
244 }
245 
253 void
254 vpXmlParser::xmlWriteCharChild(xmlNodePtr node, const char* label, const char* value)
255 {
256  xmlNodePtr tmp;
257  tmp = xmlNewChild(node, NULL, (xmlChar*)label, (xmlChar*)value);
258  xmlAddChild(node, tmp);
259 }
260 
268 void
269 vpXmlParser::xmlWriteStringChild(xmlNodePtr node, const char* label, const std::string& value)
270 {
271  xmlNodePtr tmp;
272  tmp = xmlNewChild(node, NULL, (xmlChar*)label, (xmlChar*)value.c_str());
273  xmlAddChild(node, tmp);
274 }
275 
276 
284 void
285 vpXmlParser::xmlWriteIntChild(xmlNodePtr node, const char* label, const int value)
286 {
287  char str[100];
288  sprintf(str, "%d", value);
289  xmlNodePtr tmp;
290  tmp = xmlNewChild(node, NULL, (xmlChar*)label, (xmlChar*)str);
291  xmlAddChild(node, tmp);
292 }
293 
301 void
302 vpXmlParser::xmlWriteUnsignedIntChild(xmlNodePtr node, const char* label, const unsigned int value)
303 {
304  char str[100];
305  sprintf(str, "%u", value);
306  xmlNodePtr tmp;
307  tmp = xmlNewChild(node, NULL, (xmlChar*)label, (xmlChar*)str);
308  xmlAddChild(node, tmp);
309 }
310 
311 
319 void
320 vpXmlParser::xmlWriteDoubleChild(xmlNodePtr node, const char* label, const double value)
321 {
322  char str[100];
323  sprintf(str, "%lf", value);
324  xmlNodePtr tmp;
325  tmp = xmlNewChild(node, NULL, (xmlChar*)label, (xmlChar*)str);
326  xmlAddChild(node, tmp);
327 }
328 
329 
330 /* -------------------------------------------------------------------------- */
331 /* MAIN METHODS */
332 /* -------------------------------------------------------------------------- */
333 
342 void
343 vpXmlParser::parse(const std::string& filename)
344 {
345  xmlDocPtr doc;
346  xmlNodePtr root_node;
347 
348  doc = xmlParseFile(filename.c_str());
349  if(doc == NULL){
350  vpERROR_TRACE("cannot open file");
351  throw vpException(vpException::ioError, "cannot open file");
352  }
353 
354  root_node = xmlDocGetRootElement(doc);
355  if(root_node == NULL){
356  vpERROR_TRACE("cannot get root element");
357  throw vpException(vpException::ioError, "cannot get root element");
358  }
359 
360  readMainClass(doc, root_node);
361 
362  xmlFreeDoc(doc);
363 }
364 
375 void
376 vpXmlParser::save(const std::string& filename, const bool append)
377 {
378  xmlDocPtr doc;
379  xmlNodePtr root_node;
380 
381  doc = xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOWARNING + XML_PARSE_NOERROR + XML_PARSE_NOBLANKS);
382  if (doc == NULL){
383  doc = xmlNewDoc ((xmlChar*)"1.0");
384  root_node = xmlNewNode(NULL, (xmlChar*)main_tag.c_str());
385  xmlDocSetRootElement(doc, root_node);
386  }
387  else{
388  if(!append){
389  xmlFreeDoc(doc);
390  if (remove(filename.c_str()) != 0)
391  throw vpException(vpException::ioError, "Cannot remove existing xml file");
392 
393  doc = xmlNewDoc ((xmlChar*)"1.0");
394  root_node = xmlNewNode(NULL, (xmlChar*)main_tag.c_str());
395  xmlDocSetRootElement(doc, root_node);
396  }
397  }
398 
399  root_node = xmlDocGetRootElement(doc);
400  if (root_node == NULL)
401  {
402  vpERROR_TRACE("problem to get the root node");
403  throw vpException(vpException::ioError, "problem to get the root node");
404  }
405 
406  writeMainClass(root_node);
407 
408  xmlSaveFormatFile(filename.c_str(), doc, 1);
409  xmlFreeDoc(doc);
410 }
411 
412 
413 
414 
415 #endif
416 
417 
418 
419 
std::string main_tag
Definition: vpXmlParser.h:202
void xmlWriteIntChild(xmlNodePtr node, const char *label, const int value)
virtual ~vpXmlParser()
Definition: vpXmlParser.cpp:79
#define vpERROR_TRACE
Definition: vpDebug.h:395
error that can be emited by ViSP classes.
Definition: vpException.h:76
virtual void writeMainClass(xmlNodePtr node)=0
double xmlReadDoubleChild(xmlDocPtr doc, xmlNodePtr node)
char * xmlReadCharChild(xmlDocPtr doc, xmlNodePtr node)
void save(const std::string &filename, const bool append=false)
This class intends to simplify the creation of xml parser based on the libxml2 third party library...
Definition: vpXmlParser.h:178
void xmlWriteUnsignedIntChild(xmlNodePtr node, const char *label, const unsigned int value)
void xmlWriteDoubleChild(xmlNodePtr node, const char *label, const double value)
void xmlWriteCharChild(xmlNodePtr node, const char *label, const char *value)
int xmlReadIntChild(xmlDocPtr doc, xmlNodePtr node)
virtual void readMainClass(xmlDocPtr doc, xmlNodePtr node)=0
unsigned int xmlReadUnsignedIntChild(xmlDocPtr doc, xmlNodePtr node)
std::string xmlReadStringChild(xmlDocPtr doc, xmlNodePtr node)
void xmlWriteStringChild(xmlNodePtr node, const char *label, const std::string &value)
std::map< std::string, int > nodeMap
Definition: vpXmlParser.h:197
void parse(const std::string &filename)