Goby Underwater Autonomy Project
Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
|
00001 // copyright 2010 t. schneider tes@mit.edu 00002 // ocean engineering graudate student - mit / whoi joint program 00003 // massachusetts institute of technology (mit) 00004 // laboratory for autonomous marine sensing systems (lamss) 00005 // 00006 // this file is part of goby-util, a collection of utility libraries 00007 // 00008 // 00009 // This program is free software: you can redistribute it and/or modify 00010 // it under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation, either version 3 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // This software is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with this software. If not, see <http://www.gnu.org/licenses/>. 00021 00022 #ifndef STRING20100713H 00023 #define STRING20100713H 00024 00025 #include <string> 00026 #include <vector> 00027 #include <boost/lexical_cast.hpp> 00028 #include <iostream> 00029 #include <limits> 00030 #include <boost/utility.hpp> 00031 #include <boost/type_traits.hpp> 00032 #include <boost/algorithm/string.hpp> 00033 00034 namespace goby 00035 { 00036 00037 namespace util 00038 { 00040 00041 00046 template<typename To, typename From> 00047 To as(From from, typename boost::enable_if<boost::is_fundamental<To> >::type* dummy = 0) 00048 { 00049 try { return boost::lexical_cast<To>(from); } 00050 catch(boost::bad_lexical_cast&) 00051 { 00052 // return NaN or minimum value supported by the type 00053 return std::numeric_limits<To>::has_quiet_NaN 00054 ? std::numeric_limits<To>::quiet_NaN() 00055 : std::numeric_limits<To>::min(); 00056 } 00057 } 00058 00063 template<typename To, typename From> 00064 To as(From from, typename boost::disable_if<boost::is_fundamental<To> >::type* dummy = 0) 00065 { 00066 try { return boost::lexical_cast<To>(from); } 00067 catch(boost::bad_lexical_cast&) 00068 { 00069 return To(); 00070 } 00071 } 00072 00074 template <> 00075 inline bool as<bool, std::string>(std::string from, void* dummy) 00076 { 00077 return (boost::iequals(from, "true") || boost::iequals(from, "1")); 00078 } 00079 00081 template <> 00082 inline std::string as<std::string, bool>(bool from, void* dummy) 00083 { 00084 std::stringstream ss; 00085 ss << std::boolalpha << from; 00086 return ss.str(); 00087 } 00088 00089 00090 00092 inline void stripblanks(std::string& s) 00093 { 00094 for(std::string::iterator it=s.end()-1; it!=s.begin()-1; --it) 00095 { 00096 if(isspace(*it)) 00097 s.erase(it); 00098 } 00099 } 00100 00101 00102 00112 inline bool val_from_string(std::string& out, const std::string& str, const std::string & key) 00113 { 00114 // str: foo=1,bar={2,3,4,5},pig=3,cow=yes 00115 // two cases: 00116 // key: bar 00117 // key: pig 00118 00119 out.erase(); 00120 00121 // str: foo=1,bar={2,3,4,5},pig=3,cow=yes 00122 // start_pos ^ ^ 00123 std::string::size_type start_pos = str.find(std::string(key+"=")); 00124 00125 // deal with foo=bar,o=bar problem when looking for "o=" since 00126 // o is contained in foo 00127 00128 // ok: beginning of string, end of string, comma right before start_pos 00129 while(!(start_pos == 0 || start_pos == std::string::npos || str[start_pos-1] == ',')) 00130 start_pos = str.find(std::string(key+"="), start_pos+1); 00131 00132 if(start_pos != std::string::npos) 00133 { 00134 // chopped: bar={2,3,4,5},pig=3,cow=yes 00135 // chopped: pig=3,cow=yes 00136 std::string chopped = str.substr(start_pos); 00137 00138 // chopped: bar={2,3,4,5},pig=3,cow=yes 00139 // equal_pos ^ 00140 // chopped: pig=3,cow=yes 00141 // equal_pos ^ 00142 std::string::size_type equal_pos = chopped.find("="); 00143 00144 // check for array 00145 bool is_array = (equal_pos+1 < chopped.length() && chopped[equal_pos+1] == '{'); 00146 00147 if(equal_pos != std::string::npos) 00148 { 00149 // chopped_twice: ={2,3,4,5},pig=3,cow=yes 00150 // chopped_twice: =pig=3,cow=yes 00151 std::string chopped_twice = chopped.substr(equal_pos); 00152 00153 // chopped_twice: ={2,3,4,5},pig=3,cow=yes 00154 // end_pos ^ 00155 // chopped_twice: =pig=3,cow=yes 00156 // end_pos ^ 00157 std::string::size_type end_pos = 00158 (is_array) ? chopped_twice.find("}") : chopped_twice.find(","); 00159 00160 // out: 2,3,4,5 00161 // out: 3 00162 out = (is_array) ? chopped_twice.substr(2, end_pos-2) : chopped_twice.substr(1, end_pos-1); 00163 00164 return true; 00165 } 00166 } 00167 00168 return false; 00169 } 00170 00173 template<typename T> 00174 inline bool val_from_string(T& out, const std::string& str, const std::string & key) 00175 { 00176 std::string s; 00177 if(!val_from_string(s, str, key)) return false; 00178 00179 try { out = boost::lexical_cast<T>(s); } 00180 catch (boost::bad_lexical_cast&) 00181 { return false; } 00182 00183 return true; 00184 } 00185 00186 00188 inline bool val_from_string(bool& out, const std::string& str, const std::string & key) 00189 { 00190 std::string s; 00191 if(!val_from_string(s, str, key)) return false; 00192 00193 out = as<bool>(s); 00194 return true; 00195 } 00197 } 00198 } 00199 #endif 00200