names.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009, Willow Garage, Inc.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *   * Redistributions of source code must retain the above copyright notice,
00007  *     this list of conditions and the following disclaimer.
00008  *   * Redistributions in binary form must reproduce the above copyright
00009  *     notice, this list of conditions and the following disclaimer in the
00010  *     documentation and/or other materials provided with the distribution.
00011  *   * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
00012  *     contributors may be used to endorse or promote products derived from
00013  *     this software without specific prior written permission.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025  * POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 
00028 #include "ros/names.h"
00029 #include "ros/this_node.h"
00030 #include "ros/file_log.h"
00031 
00032 #include <ros/console.h>
00033 #include <ros/assert.h>
00034 
00035 #include <cstring>
00036 
00037 namespace ros
00038 {
00039 
00040 namespace names
00041 {
00042 
00043 M_string g_remappings;
00044 M_string g_unresolved_remappings;
00045 
00046 const M_string& getRemappings()
00047 {
00048   return g_remappings;
00049 }
00050 
00051 const M_string& getUnresolvedRemappings()
00052 {
00053   return g_unresolved_remappings;
00054 }
00055 
00056 bool isValidCharInName(char c)
00057 {
00058   if (isalnum(c) || c == '/' || c == '_')
00059   {
00060     return true;
00061   }
00062 
00063   return false;
00064 }
00065 
00066 bool validate(const std::string& name, std::string& error)
00067 {
00068   if (name.empty())
00069   {
00070     return true;
00071   }
00072 
00073   // First element is special, can be only ~ / or alpha
00074   char c = name[0];
00075   if (!isalpha(c) && c != '/' && c != '~')
00076   {
00077     std::stringstream ss;
00078     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 ~.";
00079     error = ss.str();
00080     return false;
00081   }
00082 
00083   for (size_t i = 1; i < name.size(); ++i)
00084   {
00085     c = name[i];
00086     if (!isValidCharInName(c))
00087     {
00088       std::stringstream ss;
00089       ss << "Character [" << c << "] at element [" << i << "] is not valid in Graph Resource Name [" << name <<"].  Valid characters are a-z, A-Z, 0-9, / and _.";
00090       error = ss.str();
00091 
00092       return false;
00093     }
00094   }
00095 
00096   return true;
00097 }
00098 
00099 std::string clean(const std::string& name)
00100 {
00101   std::string clean = name;
00102 
00103   size_t pos = clean.find("//");
00104   while (pos != std::string::npos)
00105   {
00106     clean.erase(pos, 1);
00107     pos = clean.find("//", pos);
00108   }
00109 
00110   if (*clean.rbegin() == '/')
00111   {
00112     clean.erase(clean.size() - 1, 1);
00113   }
00114 
00115   return clean;
00116 }
00117 
00118 std::string append(const std::string& left, const std::string& right)
00119 {
00120   return clean(left + "/" + right);
00121 }
00122 
00123 std::string remap(const std::string& name)
00124 {
00125   std::string resolved = resolve(name, false);
00126 
00127   M_string::const_iterator it = g_remappings.find(resolved);
00128   if (it != g_remappings.end())
00129   {
00130     return it->second;
00131   }
00132 
00133   return name;
00134 }
00135 
00136 std::string resolve(const std::string& name, bool _remap)
00137 {
00138   std::string s = resolve(this_node::getNamespace(), name, _remap);
00139   return s;
00140 }
00141 
00142 std::string resolve(const std::string& ns, const std::string& name, bool _remap)
00143 {
00144   std::string error;
00145   if (!validate(name, error))
00146   {
00147         throw InvalidNameException(error);
00148   }
00149 
00150   if (name.empty())
00151   {
00152     if (ns.empty())
00153     {
00154       return "/";
00155     }
00156 
00157     if (ns[0] == '/')
00158     {
00159       return ns;
00160     }
00161 
00162     return append("/", ns);
00163   }
00164 
00165   std::string copy = name;
00166 
00167   if (copy[0] == '~')
00168   {
00169     copy = append(this_node::getName(), copy.substr(1));
00170   }
00171 
00172   if (copy[0] != '/')
00173   {
00174     copy = append("/", append(ns, copy));
00175   }
00176 
00177   copy = clean(copy);
00178 
00179   if (_remap)
00180   {
00181     copy = remap(copy);
00182   }
00183 
00184   return copy;
00185 }
00186 
00187 void init(const M_string& remappings)
00188 {
00189   M_string::const_iterator it = remappings.begin();
00190   M_string::const_iterator end = remappings.end();
00191   for (; it != end; ++it)
00192   {
00193     const std::string& left = it->first;
00194     const std::string& right = it->second;
00195 
00196     if (!left.empty() && left[0] != '_' && left != this_node::getName())
00197     {
00198       std::string resolved_left = resolve(left, false);
00199       std::string resolved_right = resolve(right, false);
00200       g_remappings[resolved_left] = resolved_right;
00201       g_unresolved_remappings[left] = right;
00202     }
00203   }
00204 }
00205 
00206 std::string parentNamespace(const std::string& name)
00207 {
00208   std::string error;
00209   if (!validate(name, error))
00210   {
00211         throw InvalidNameException(error);
00212   }
00213 
00214   if (!name.compare(""))  return "";
00215   if (!name.compare("/")) return "/"; 
00216 
00217   std::string stripped_name;
00218 
00219   // rstrip trailing slash
00220   if (name.find_last_of('/') == name.size()-1)
00221     stripped_name = name.substr(0, name.size() -2);
00222   else
00223     stripped_name = name;
00224 
00225   //pull everything up to the last /
00226   size_t last_pos = stripped_name.find_last_of('/');
00227   if (last_pos == std::string::npos)
00228   {
00229     return "";
00230   }
00231   else if (last_pos == 0)
00232     return "/";
00233   return stripped_name.substr(0, last_pos);
00234 }
00235 
00236 } // namespace names
00237 
00238 } // namespace ros


roscpp
Author(s): Morgan Quigley mquigley@cs.stanford.edu, Josh Faust jfaust@willowgarage.com, Brian Gerkey gerkey@willowgarage.com, Troy Straszheim straszheim@willowgarage.com
autogenerated on Sat Dec 28 2013 17:35:52