xml_utils.cpp
Go to the documentation of this file.
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014-2020 Jose Luis Blanco Claraco |
5  | Copyright (C) 2017 Borys Tymchenko (Odessa Polytechnic University) |
6  | Distributed under 3-clause BSD License |
7  | See COPYING |
8  +-------------------------------------------------------------------------+ */
9 
10 #include "xml_utils.h"
11 
12 #include <mrpt/core/bits_math.h>
13 #include <mrpt/core/format.h>
14 #include <mrpt/img/TColor.h>
15 #include <mrpt/math/TPolygon2D.h>
16 #include <mrpt/poses/CPose2D.h>
17 #include <mrpt/poses/CPose3D.h>
19 #include <mvsim/basic_types.h>
20 
21 #include <cstdio>
22 
23 #include "parse_utils.h"
24 
25 using namespace rapidxml;
26 using namespace mvsim;
27 
33  const std::string& inStr, const std::string& varName,
34  const std::map<std::string, std::string>& variableNamesValues,
35  const char* functionNameContext) const
36 {
37  const std::string str = mvsim::parse(inStr, variableNamesValues);
38 
39  // Special cases:
40  // "%s" ==> std::strings
41  if (std::string(frmt) == std::string("%s"))
42  {
43  std::string& val2 = *reinterpret_cast<std::string*>(val);
44  val2 = mrpt::system::trim(str);
45  }
46  // "%lf_deg" ==> mrpt::DEG2RAD()
47  else if (std::string(frmt) == std::string("%lf_deg"))
48  {
49  if (1 != ::sscanf(str.c_str(), frmt, val))
50  throw std::runtime_error(mrpt::format(
51  "%s Error parsing attribute '%s'='%s' (Expected "
52  "format:'%s')",
53  functionNameContext, varName.c_str(), str.c_str(), frmt));
54  double& ang = *reinterpret_cast<double*>(val);
55  ang = mrpt::DEG2RAD(ang);
56  }
57  // "%bool" ==> bool*
58  else if (std::string(frmt) == std::string("%bool"))
59  {
60  bool& bool_val = *reinterpret_cast<bool*>(val);
61 
62  const std::string sStr =
64  if (sStr == "1" || sStr == "true")
65  bool_val = true;
66  else if (sStr == "0" || sStr == "false")
67  bool_val = false;
68  else
69  throw std::runtime_error(mrpt::format(
70  "%s Error parsing 'bool' attribute '%s'='%s' (Expected "
71  "'true' or 'false')",
72  functionNameContext, varName.c_str(), str.c_str()));
73  }
74  // "%color" ==> mrpt::img::TColor
75  else if (std::string(frmt) == std::string("%color"))
76  {
77  // HTML-like format:
78  if (!(str.size() > 1 && str[0] == '#'))
79  throw std::runtime_error(mrpt::format(
80  "%s Error parsing '%s'='%s' (Expected "
81  "format:'#RRGGBB[AA]')",
82  functionNameContext, varName.c_str(), str.c_str()));
83 
84  unsigned int r, g, b, a = 0xff;
85  int ret = ::sscanf(str.c_str() + 1, "%2x%2x%2x%2x", &r, &g, &b, &a);
86  if (ret != 3 && ret != 4)
87  throw std::runtime_error(mrpt::format(
88  "%s Error parsing '%s'='%s' (Expected "
89  "format:'#RRGGBB[AA]')",
90  functionNameContext, varName.c_str(), str.c_str()));
91  mrpt::img::TColor& col = *reinterpret_cast<mrpt::img::TColor*>(val);
92  col = mrpt::img::TColor(r, g, b, a);
93  }
94  // "%pose2d"
95  // "%pose2d_ptr3d"
96  else if (!strncmp(frmt, "%pose2d", strlen("%pose2d")))
97  {
98  double x, y, yaw;
99  int ret = ::sscanf(str.c_str(), "%lf %lf %lf", &x, &y, &yaw);
100  if (ret != 3)
101  throw std::runtime_error(mrpt::format(
102  "%s Error parsing '%s'='%s' (Expected format:'X Y "
103  "YAW_DEG')",
104  functionNameContext, varName.c_str(), str.c_str()));
105 
106  // User provides angles in deg:
107  yaw = mrpt::DEG2RAD(yaw);
108 
109  const mrpt::poses::CPose2D p(x, y, yaw);
110 
111  // Sub-cases:
112  if (!strcmp(frmt, "%pose2d"))
113  {
115  *reinterpret_cast<mrpt::poses::CPose2D*>(val);
116  pp = p;
117  }
118  else if (!strcmp(frmt, "%pose2d_ptr3d"))
119  {
121  *reinterpret_cast<mrpt::poses::CPose3D*>(val);
122  pp = mrpt::poses::CPose3D(p);
123  }
124  else
125  throw std::runtime_error(mrpt::format(
126  "%s Error: Unknown format specifier '%s'", functionNameContext,
127  frmt));
128  }
129  else
130  {
131  // Generic parse:
132  if (1 != ::sscanf(str.c_str(), frmt, val))
133  throw std::runtime_error(mrpt::format(
134  "%s Error parsing attribute '%s'='%s' (Expected "
135  "format:'%s')",
136  functionNameContext, varName.c_str(), str.c_str(), frmt));
137  }
138 }
139 
143  const std::map<std::string, std::string>& variableNamesValues,
144  const char* functionNameContext)
145 {
146  for (const auto& param : params)
147  {
148  const rapidxml::xml_attribute<char>* attr =
149  xml_node.first_attribute(param.first.c_str());
150  if (attr && attr->value())
151  param.second.parse(
152  attr->value(), attr->name(), variableNamesValues,
153  functionNameContext);
154  }
155 }
156 
160  const std::map<std::string, std::string>& variableNamesValues,
161  const char* functionNameContext)
162 {
163  TParameterDefinitions::const_iterator it_param =
164  params.find(xml_node.name());
165 
166  if (it_param != params.end())
167  {
168  // parse parameter:
169  it_param->second.parse(
170  xml_node.value(), xml_node.name(), variableNamesValues,
171  functionNameContext);
172  return true;
173  }
174  return false;
175 }
176 
181  const std::map<std::string, std::string>& variableNamesValues,
182  const char* functionNameContext)
183 {
184  rapidxml::xml_node<>* node = root.first_node();
185  while (node)
186  {
188  *node, params, variableNamesValues, functionNameContext);
189  node = node->next_sibling(nullptr); // Move on to next node
190  }
191 }
192 
199  const std::string& s, bool allow_missing_angle,
200  double default_angle_radians)
201 {
203  v.phi = mrpt::RAD2DEG(default_angle_radians); // Default ang.
204 
205  int na = ::sscanf(s.c_str(), "%lf %lf %lf", &v.x, &v.y, &v.phi);
206 
207  // User provides numbers as degrees:
208  v.phi = mrpt::DEG2RAD(v.phi);
209 
210  if ((na != 3 && !allow_missing_angle) ||
211  (na != 2 && na != 3 && allow_missing_angle))
212  throw std::runtime_error(
213  mrpt::format("Malformed pose string: '%s'", s.c_str()));
214 
215  return v;
216 }
217 
224  const char* functionNameContext)
225 {
226  out_poly.clear();
227 
228  for (rapidxml::xml_node<char>* pt_node = xml_node.first_node("pt"); pt_node;
229  pt_node = pt_node->next_sibling("pt"))
230  {
231  if (!pt_node->value())
232  throw std::runtime_error(mrpt::format(
233  "%s Error: <pt> node seems empty.", functionNameContext));
234 
236  const char* str_val = pt_node->value();
237  if (2 != ::sscanf(str_val, "%lf %lf", &pt.x, &pt.y))
238  throw std::runtime_error(mrpt::format(
239  "%s Error parsing <pt> node: '%s' (Expected format:'<pt>X "
240  "Y</pt>')",
241  functionNameContext, str_val));
242 
243  out_poly.push_back(pt);
244  }
245 
246  if (out_poly.size() < 3)
247  throw std::runtime_error(mrpt::format(
248  "%s Error: <shape> node requires 3 or more <pt>X Y</pt> "
249  "entries.",
250  functionNameContext));
251 }
GLboolean GLboolean GLboolean GLboolean a
const GLdouble * v
GLint GLint GLint GLint GLint GLint y
std::map< std::string, TParamEntry > TParameterDefinitions
Ch * value() const
Definition: rapidxml.hpp:692
GLboolean GLboolean g
void parse_xmlnode_children_as_param(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions &params, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="")
Definition: xml_utils.cpp:179
bool parse_xmlnode_as_param(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions &params, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="")
Definition: xml_utils.cpp:157
void parse_xmlnode_attribs(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions &params, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="")
Definition: xml_utils.cpp:140
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:936
GLdouble s
std::string BASE_IMPEXP lowerCase(const std::string &str)
GLint GLint GLint GLint GLint x
Ch * name() const
Definition: rapidxml.hpp:673
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
std::string parse(const std::string &input, const std::map< std::string, std::string > &variableNamesValues={})
GLfloat GLfloat p
xml_attribute< Ch > * first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:1025
xml_node< Ch > * next_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:1004
GLdouble GLdouble GLdouble r
GLfloat * params
std::string BASE_IMPEXP trim(const std::string &str)
GLuint GLfloat * val
void parse_xmlnode_shape(const rapidxml::xml_node< char > &xml_node, mrpt::math::TPolygon2D &out_poly, const char *functionNameContext="")
Definition: xml_utils.cpp:222
GLfloat param
GLdouble GLdouble GLdouble b
mrpt::math::TPose2D parseXYPHI(const std::string &s, bool allow_missing_angle=false, double default_angle_radians=0.0)
Definition: xml_utils.cpp:198


mvsim
Author(s):
autogenerated on Fri May 7 2021 03:05:51