Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
testXmlParser.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Example which describes how to use the xml parser class.
32 */
33
50
51#include <visp3/core/vpConfig.h>
52
53#include <iostream>
54#if defined(VISP_HAVE_XML2)
55
56#include <visp3/core/vpDebug.h>
57#include <visp3/core/vpIoTools.h>
58#include <visp3/core/vpXmlParser.h>
59#include <visp3/io/vpParseArgv.h>
60
61#include <libxml/parser.h>
62
63#include <string>
64
65#ifndef DOXYGEN_SHOULD_SKIP_THIS
66
67#ifdef ENABLE_VISP_NAMESPACE
68using namespace VISP_NAMESPACE_NAME;
69#endif
70
76class vpExampleDataParser : public vpXmlParser
77{
78protected:
79 double m_range;
80 int m_step;
81 int m_size_filter;
82 std::string m_name;
83
84 typedef enum { config, range, step, size_filter, name } dataToParse;
85
86public:
87 vpExampleDataParser();
88
89 // Data accessors.
90 double getRange() const { return m_range; }
91 int getStep() const { return m_step; }
92 int getSizeFilter() const { return m_size_filter; }
93 std::string getName() const { return m_name; }
94
95 void setRange(double _range) { m_range = _range; }
96 void setStep(int _step) { m_step = _step; }
97 void setSizeFilter(int _size_filter) { m_size_filter = _size_filter; }
98 void setName(const std::string &_name) { m_name = _name; }
99
100protected:
101 virtual void readMainClass(xmlDocPtr doc, xmlNodePtr node);
102 virtual void writeMainClass(xmlNodePtr node);
103};
104
110vpExampleDataParser::vpExampleDataParser() : m_range(0.), m_step(0), m_size_filter(0), m_name("")
111{
112 nodeMap["config"] = config;
113 nodeMap["range"] = range;
114 nodeMap["step"] = step;
115 nodeMap["size_filter"] = size_filter;
116 nodeMap["name"] = name;
117}
118
127void vpExampleDataParser::readMainClass(xmlDocPtr doc, xmlNodePtr node)
128{
129 for (xmlNodePtr dataNode = node->xmlChildrenNode; dataNode != nullptr; dataNode = dataNode->next) {
130 if (dataNode->type == XML_ELEMENT_NODE) {
131 std::map<std::string, int>::iterator iter_data = this->nodeMap.find((char *)dataNode->name);
132 if (iter_data != nodeMap.end()) {
133 switch (iter_data->second) {
134 case range:
135 this->m_range = xmlReadDoubleChild(doc, dataNode);
136 break;
137 case step:
138 this->m_step = xmlReadIntChild(doc, dataNode);
139 break;
140 case size_filter:
141 this->m_size_filter = xmlReadIntChild(doc, dataNode);
142 break;
143 case name: {
144 this->m_name = xmlReadStringChild(doc, dataNode);
145 } break;
146 default:
147 vpTRACE("unknown tag in readConfigNode : %d, %s", iter_data->second, (iter_data->first).c_str());
148 break;
149 }
150 }
151 }
152 }
153}
154
162void vpExampleDataParser::writeMainClass(xmlNodePtr node)
163{
164 xmlWriteDoubleChild(node, (const char *)"range", m_range);
165 xmlWriteIntChild(node, (const char *)"step", m_step);
166 xmlWriteIntChild(node, (const char *)"size_filter", m_size_filter);
167 xmlWriteCharChild(node, (const char *)"name", m_name.c_str());
168}
169
170#endif // doxygen
171
172/* -------------------------------------------------------------------------- */
173/* COMMAND LINE OPTIONS */
174/* -------------------------------------------------------------------------- */
175
176 // List of allowed command line options
177#define GETOPTARGS "cdo:h"
178
179void usage(const char *name, const char *badparam, const std::string &opath, const std::string &user);
180bool getOptions(int argc, const char **argv, std::string &opath, const std::string &user);
181
190void usage(const char *name, const char *badparam, const std::string &opath, const std::string &user)
191{
192 fprintf(stdout, "\n\
193Write and read data in a xml file.\n\
194 \n\
195SYNOPSIS\n\
196 %s [-o <output image path>] [-h]\n",
197 name);
198
199 fprintf(stdout, "\n\
200OPTIONS: Default\n\
201 -o <output data path> %s\n\
202 Set data output path.\n\
203 From this directory, creates the \"%s\"\n\
204 subdirectory depending on the username, where \n\
205 dataTestXml.xml file is written.\n\
206 \n\
207 -h\n\
208 Print the help.\n\n",
209 opath.c_str(), user.c_str());
210
211 if (badparam) {
212 fprintf(stderr, "ERROR: \n");
213 fprintf(stderr, "\nBad parameter [%s]\n", badparam);
214 }
215}
216
226bool getOptions(int argc, const char **argv, std::string &opath, const std::string &user)
227{
228 const char *optarg_;
229 int c;
230 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
231
232 switch (c) {
233 case 'o':
234 opath = optarg_;
235 break;
236 case 'h':
237 usage(argv[0], nullptr, opath, user);
238 return false;
239
240 case 'c':
241 case 'd':
242 break;
243
244 default:
245 usage(argv[0], optarg_, opath, user);
246 return false;
247 }
248 }
249
250 if ((c == 1) || (c == -1)) {
251 // standalone param or error
252 usage(argv[0], nullptr, opath, user);
253 std::cerr << "ERROR: " << std::endl;
254 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
255 return false;
256 }
257
258 return true;
259}
260
261/* -------------------------------------------------------------------------- */
262/* MAIN FUNCTION */
263/* -------------------------------------------------------------------------- */
264
265int main(int argc, const char **argv)
266{
267 try {
268 std::string opt_opath;
269 std::string opath;
270 std::string filename;
271 std::string username;
272
273 std::cout << "-------------------------------------------------------" << std::endl;
274 std::cout << " testXmlParser.cpp" << std::endl << std::endl;
275 std::cout << " writing and readind data using a xml parser" << std::endl;
276 std::cout << "-------------------------------------------------------" << std::endl;
277 std::cout << std::endl;
278
279 // Set the default output path
280#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
281 opt_opath = "/tmp";
282#elif defined(_WIN32)
283 opt_opath = "C:\\temp";
284#endif
285
286 // Get the user login name
287 vpIoTools::getUserName(username);
288
289 // Read the command line options
290 if (getOptions(argc, argv, opt_opath, username) == false) {
291 return EXIT_FAILURE;
292 }
293
294 // Get the option values
295 if (!opt_opath.empty())
296 opath = opt_opath;
297
298 // Append to the output path string, the login name of the user
299 std::string dirname = vpIoTools::createFilePath(opath, username);
300
301 // Test if the output path exist. If no try to create it
302 if (vpIoTools::checkDirectory(dirname) == false) {
303 try {
304 // Create the dirname
306 }
307 catch (...) {
308 usage(argv[0], nullptr, opath, username);
309 std::cerr << std::endl << "ERROR:" << std::endl;
310 std::cerr << " Cannot create " << dirname << std::endl;
311 std::cerr << " Check your -o " << opath << " option " << std::endl;
312 return EXIT_FAILURE;
313 }
314 }
315
316 filename = dirname + vpIoTools::path("/") + "dataTestXml.xml";
317
318 // Write data using a parser.
319 {
320 vpExampleDataParser parser1;
321
322 // Acquire data from measurments or tests.
323 parser1.setRange(3.5);
324 parser1.setStep(2);
325 parser1.setSizeFilter(5);
326 parser1.setName("cube");
327
328 std::cout << "Write data to " << filename << std::endl;
329 parser1.save(filename);
330 }
331
332 // Read data using another parser.
333 {
334 vpExampleDataParser parser2;
335
336 parser2.parse(filename);
337
338 std::cout << "Read from " << filename << std::endl;
339 std::cout << "Range : " << parser2.getRange() << std::endl;
340 std::cout << "Step : " << parser2.getStep() << std::endl;
341 std::cout << "Filter size : " << parser2.getSizeFilter() << std::endl;
342 std::cout << "name : " << parser2.getName() << std::endl;
343 }
344
345 // Clean up memory allocated by the xml library
347 return EXIT_SUCCESS;
348 }
349 catch (const vpException &e) {
350 std::cout << "Catch an exception: " << e << std::endl;
351 return EXIT_FAILURE;
352 }
353}
354
355#else
356
357int main()
358{
359 std::cout << "Xml parser requires libxml2." << std::endl;
360 return EXIT_SUCCESS;
361}
362#endif
error that can be emitted by ViSP classes.
Definition vpException.h:60
static std::string path(const std::string &pathname)
static bool checkDirectory(const std::string &dirname)
static std::string getUserName()
static std::string createFilePath(const std::string &parent, const std::string &child)
static void makeDirectory(const std::string &dirname)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
static void cleanup()
virtual void readMainClass(xmlDocPtr doc, xmlNodePtr node)=0
virtual void writeMainClass(xmlNodePtr node)=0
#define vpTRACE
Definition vpDebug.h:450