names.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009, Willow Garage, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution.
11  * * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "ros/names.h"
29 #include "ros/this_node.h"
30 #include "ros/file_log.h"
31 
32 #include <ros/console.h>
33 #include <ros/assert.h>
34 
35 #include <cstring>
36 
37 namespace ros
38 {
39 
40 namespace names
41 {
42 
45 
47 {
48  return g_remappings;
49 }
50 
52 {
54 }
55 
56 bool isValidCharInName(char c)
57 {
58  if (isalnum(c) || c == '/' || c == '_')
59  {
60  return true;
61  }
62 
63  return false;
64 }
65 
66 bool validate(const std::string& name, std::string& error)
67 {
68  if (name.empty())
69  {
70  return true;
71  }
72 
73  // First element is special, can be only ~ / or alpha
74  char c = name[0];
75  if (!isalpha(c) && c != '/' && c != '~')
76  {
77  std::stringstream ss;
78  ss << "Character [" << c << "] is not valid as the first character in Graph Resource Name [" << name << "]. Valid characters are a-z, A-Z, / and in some cases ~.";
79  error = ss.str();
80  return false;
81  }
82 
83  for (size_t i = 1; i < name.size(); ++i)
84  {
85  c = name[i];
86  if (!isValidCharInName(c))
87  {
88  std::stringstream ss;
89  ss << "Character [" << c << "] at element [" << i << "] is not valid in Graph Resource Name [" << name <<"]. Valid characters are a-z, A-Z, 0-9, / and _.";
90  error = ss.str();
91 
92  return false;
93  }
94  }
95 
96  return true;
97 }
98 
99 std::string clean(const std::string& name)
100 {
101  std::string clean = name;
102 
103  size_t pos = clean.find("//");
104  while (pos != std::string::npos)
105  {
106  clean.erase(pos, 1);
107  pos = clean.find("//", pos);
108  }
109 
110  if (!name.empty() && *clean.rbegin() == '/')
111  {
112  clean.erase(clean.size() - 1, 1);
113  }
114 
115  return clean;
116 }
117 
118 std::string append(const std::string& left, const std::string& right)
119 {
120  return clean(left + "/" + right);
121 }
122 
123 std::string remap(const std::string& name)
124 {
125  std::string resolved = resolve(name, false);
126 
127  M_string::const_iterator it = g_remappings.find(resolved);
128  if (it != g_remappings.end())
129  {
130  return it->second;
131  }
132 
133  return name;
134 }
135 
136 std::string resolve(const std::string& name, bool _remap)
137 {
138  std::string s = resolve(this_node::getNamespace(), name, _remap);
139  return s;
140 }
141 
142 std::string resolve(const std::string& ns, const std::string& name, bool _remap)
143 {
144  std::string error;
145  if (!validate(name, error))
146  {
147  throw InvalidNameException(error);
148  }
149 
150  if (name.empty())
151  {
152  if (ns.empty())
153  {
154  return "/";
155  }
156 
157  if (ns[0] == '/')
158  {
159  return ns;
160  }
161 
162  return append("/", ns);
163  }
164 
165  std::string copy = name;
166 
167  if (copy[0] == '~')
168  {
169  copy = append(this_node::getName(), copy.substr(1));
170  }
171 
172  if (copy[0] != '/')
173  {
174  copy = append("/", append(ns, copy));
175  }
176 
177  copy = clean(copy);
178 
179  if (_remap)
180  {
181  copy = remap(copy);
182  }
183 
184  return copy;
185 }
186 
187 void init(const M_string& remappings)
188 {
189  M_string::const_iterator it = remappings.begin();
190  M_string::const_iterator end = remappings.end();
191  for (; it != end; ++it)
192  {
193  const std::string& left = it->first;
194  const std::string& right = it->second;
195 
196  if (!left.empty() && left[0] != '_' && left != this_node::getName())
197  {
198  std::string resolved_left = resolve(left, false);
199  std::string resolved_right = resolve(right, false);
200  g_remappings[resolved_left] = resolved_right;
201  g_unresolved_remappings[left] = right;
202  }
203  }
204 }
205 
206 std::string parentNamespace(const std::string& name)
207 {
208  std::string error;
209  if (!validate(name, error))
210  {
211  throw InvalidNameException(error);
212  }
213 
214  if (!name.compare("")) return "";
215  if (!name.compare("/")) return "/";
216 
217  std::string stripped_name;
218 
219  // rstrip trailing slash
220  if (name.find_last_of('/') == name.size()-1)
221  stripped_name = name.substr(0, name.size() -2);
222  else
223  stripped_name = name;
224 
225  //pull everything up to the last /
226  size_t last_pos = stripped_name.find_last_of('/');
227  if (last_pos == std::string::npos)
228  {
229  return "";
230  }
231  else if (last_pos == 0)
232  return "/";
233  return stripped_name.substr(0, last_pos);
234 }
235 
236 } // namespace names
237 
238 } // namespace ros
M_string g_remappings
Definition: names.cpp:43
M_string g_unresolved_remappings
Definition: names.cpp:44
bool isValidCharInName(char c)
Definition: names.cpp:56
ROSCPP_DECL std::string parentNamespace(const std::string &name)
Get the parent namespace of a name.
Definition: names.cpp:206
XmlRpcServer s
ROSCPP_DECL const std::string & getName()
Returns the name of the current node.
Definition: this_node.cpp:74
ROSCPP_DECL bool validate(const std::string &name, std::string &error)
Validate a name against the name spec.
Definition: names.cpp:66
ROSCPP_DECL std::string resolve(const std::string &name, bool remap=true)
Resolve a graph resource name into a fully qualified graph resource name.
Definition: names.cpp:136
ROSCPP_DECL std::string clean(const std::string &name)
Cleans a graph resource name: removes double slashes, trailing slash.
Definition: names.cpp:99
ROSCPP_DECL const M_string & getRemappings()
Definition: names.cpp:46
std::map< std::string, std::string > M_string
void init(const M_string &remappings)
Definition: names.cpp:187
ROSCPP_DECL std::string remap(const std::string &name)
Apply remappings to a name.
Definition: names.cpp:123
ROSCPP_DECL const std::string & getNamespace()
Returns the namespace of the current node.
Definition: this_node.cpp:79
ROSCPP_DECL const M_string & getUnresolvedRemappings()
Definition: names.cpp:51
Thrown when an invalid graph resource name is specified to any roscpp function.
Definition: exceptions.h:51
ROSCPP_DECL std::string append(const std::string &left, const std::string &right)
Append one name to another.
Definition: names.cpp:118


roscpp
Author(s): Morgan Quigley, Josh Faust, Brian Gerkey, Troy Straszheim, Dirk Thomas
autogenerated on Mon Feb 28 2022 23:33:27