ros_field.cpp
Go to the documentation of this file.
1 /***** MIT License ****
2  *
3  * Copyright (c) 2016-2022 Davide Faconti
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #include <algorithm>
25 #include <regex>
28 
29 namespace RosMsgParser
30 {
31 
32 ROSField::ROSField(const ROSType& type, const std::string& name)
33  : _fieldname(name), _type(type), _is_array(false), _array_size(1)
34 {
35 }
36 
37 ROSField::ROSField(const std::string& definition) : _is_array(false), _array_size(1)
38 {
39  static const std::regex type_regex("[a-zA-Z][a-zA-Z0-9_]*"
40  "(/[a-zA-Z][a-zA-Z0-9_]*){0,1}"
41  "(\\[[0-9]*\\]){0,1}");
42 
43  static const std::regex field_regex("[a-zA-Z][a-zA-Z0-9_]*");
44 
45  static const std::regex array_regex("(.+)(\\[([0-9]*)\\])");
46 
47  using std::regex;
48  std::string::const_iterator begin = definition.begin();
49  std::string::const_iterator end = definition.end();
50  std::match_results<std::string::const_iterator> what;
51 
52  // Get type and field
53  std::string type, value;
54 
55  //-------------------------------
56  // Find type, field and array size
57  if (std::regex_search(begin, end, what, type_regex))
58  {
59  type = what[0];
60  begin = what[0].second;
61  }
62  else
63  {
64  throw std::runtime_error("Bad type when parsing field: " + definition);
65  }
66 
67  if (regex_search(begin, end, what, field_regex))
68  {
69  _fieldname = what[0];
70  begin = what[0].second;
71  }
72  else
73  {
74  throw std::runtime_error("Bad field when parsing field: " + definition);
75  }
76 
77  std::string temp_type = type;
78  if (regex_search(temp_type, what, array_regex))
79  {
80  type = what[1];
81 
82  if (what.size() == 3)
83  {
84  _array_size = -1;
85  _is_array = true;
86  }
87  else if (what.size() == 4)
88  {
89  std::string size(what[3].first, what[3].second);
90  _array_size = size.empty() ? -1 : atoi(size.c_str());
91  _is_array = true;
92  }
93  else
94  {
95  throw std::runtime_error("Bad array size when parsing field: " + definition);
96  }
97  }
98 
99  //-------------------------------
100  // Find if Constant or comment
101 
102  // Determine next character
103  // if '=' -> constant, if '#' -> done, if nothing -> done, otherwise error
104  if (regex_search(begin, end, what, std::regex("\\S")))
105  {
106  if (what[0] == "=")
107  {
108  begin = what[0].second;
109  // Copy constant
110  if (type == "string")
111  {
112  value.assign(begin, end);
113  }
114  else
115  {
116  if (regex_search(begin, end, what, std::regex("\\s*#")))
117  {
118  value.assign(begin, what[0].first);
119  }
120  else
121  {
122  value.assign(begin, end);
123  }
124  }
125 
126  TrimString(value);
127  _is_constant = true;
128  }
129  else if (what[0] == "#")
130  {
131  // Ignore comment
132  }
133  else // default value, not constant ?
134  {
135  if (regex_search(begin, end, what, std::regex("\\s*#")))
136  {
137  value.assign(begin, what[0].first);
138  }
139  else
140  {
141  value.assign(begin, end);
142  }
143  }
144  }
145  _type = ROSType(type);
146  // TODO: Raise error if string is not numeric ?
147  _value = value;
148 }
149 
150 std::shared_ptr<ROSMessage>
151 ROSField::getMessagePtr(const RosMessageLibrary& library) const
152 {
154  {
155  return {};
156  }
157  if (&library == _cache_library && _cache_message)
158  {
159  return _cache_message;
160  }
161  auto it = library.find(_type.baseName());
162  if (it == library.end())
163  {
164  return nullptr;
165  }
166  _cache_library = &library;
167  _cache_message = it->second;
168  return _cache_message;
169 }
170 
171 void TrimStringLeft(std::string& s)
172 {
173  s.erase(s.begin(), std::find_if(s.begin(), s.end(),
174  [](unsigned char ch) { return !std::isspace(ch); }));
175 }
176 
177 void TrimStringRight(std::string& s)
178 {
179  s.erase(std::find_if(s.rbegin(), s.rend(),
180  [](unsigned char ch) { return !std::isspace(ch); })
181  .base(),
182  s.end());
183 }
184 
185 void TrimString(std::string& s)
186 {
187  TrimStringLeft(s);
188  TrimStringRight(s);
189 }
190 
191 } // namespace RosMsgParser
detail::first
auto first(const T &value, const Tail &...) -> const T &
Definition: compile.h:60
RosMsgParser::ROSField::type
const ROSType & type() const
Definition: ros_field.hpp:58
RosMsgParser::ROSType
ROSType.
Definition: ros_type.hpp:39
RosMsgParser::ROSType::typeID
BuiltinType typeID() const
If type is builtin, returns the id. BuiltinType::OTHER otherwise.
Definition: ros_type.hpp:138
RosMsgParser::ROSField::ROSField
ROSField(const ROSType &type, const std::string &name)
Definition: ros_field.cpp:32
RosMsgParser::ROSField::getMessagePtr
std::shared_ptr< ROSMessage > getMessagePtr(const RosMessageLibrary &library) const
definition
const char * definition()
s
XmlRpcServer s
RosMsgParser::TrimStringLeft
void TrimStringLeft(std::string &s)
RosMsgParser::ROSField::_type
ROSType _type
Definition: ros_field.hpp:99
RosMsgParser::ROSField::value
const std::string & value() const
If constant, value of field, else undefined.
Definition: ros_field.hpp:75
ros_message.hpp
RosMsgParser::ROSField::_array_size
int _array_size
Definition: ros_field.hpp:103
RosMsgParser::ROSField::_is_array
bool _is_array
Definition: ros_field.hpp:101
RosMsgParser::ROSField::_cache_message
std::shared_ptr< ROSMessage > _cache_message
Definition: ros_field.hpp:106
RosMsgParser::TrimStringRight
void TrimStringRight(std::string &s)
nonstd::span_lite::size
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1554
RosMsgParser::RosMessageLibrary
std::unordered_map< ROSType, std::shared_ptr< ROSMessage > > RosMessageLibrary
Definition: ros_field.hpp:38
RosMsgParser
Definition: builtin_types.hpp:34
RosMsgParser::ROSField::_value
std::string _value
Definition: ros_field.hpp:100
RosMsgParser::OTHER
@ OTHER
Definition: builtin_types.hpp:61
RosMsgParser::TrimString
void TrimString(std::string &s)
RosMsgParser::ROSType::baseName
const std::string & baseName() const
Definition: ros_type.hpp:113
ros_field.hpp
RosMsgParser::ROSField::_is_constant
bool _is_constant
Definition: ros_field.hpp:102
RosMsgParser::ROSField::_fieldname
std::string _fieldname
Definition: ros_field.hpp:98
RosMsgParser::ROSField::_cache_library
const RosMessageLibrary * _cache_library
Definition: ros_field.hpp:105


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:46