00001 /*!@file Util/StringConversions.C Convert to and from std::string */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/StringConversions.C $ 00035 // $Id: StringConversions.C 11934 2009-11-06 03:03:46Z itti $ 00036 // 00037 00038 #include "Util/StringConversions.H" 00039 00040 #include "Util/StringConversions.H" 00041 #include "Util/log.H" 00042 #include "Util/sformat.H" 00043 #include "rutz/demangle.h" 00044 #include "rutz/error_context.h" 00045 00046 #include <iomanip> 00047 #include <limits> 00048 #include <netinet/in.h> // for in_addr 00049 #include <sstream> 00050 00051 namespace 00052 { 00053 template <class T> 00054 std::string basictype_to_string(const T& val) 00055 { 00056 std::stringstream s; 00057 s << val; 00058 return s.str(); 00059 } 00060 00061 template <class T> inline 00062 void string_to_basictype(const std::string& str, T& val) 00063 { 00064 std::stringstream s; 00065 s << str; 00066 s >> val; 00067 if (s.fail()) 00068 conversion_error::raise<T>(str); 00069 00070 // now make sure there is no trailing junk in the string: 00071 s >> std::ws; 00072 std::string junk; 00073 s >> junk; 00074 if (!junk.empty()) 00075 conversion_error::raise<T> 00076 (str, sformat("found extra character(s) '%s' " 00077 "following a valid conversion", 00078 junk.c_str())); 00079 } 00080 00081 class real_conversion_error : public conversion_error 00082 { 00083 public: 00084 real_conversion_error(const std::type_info& type, 00085 const std::string& str, 00086 const std::string& extrainfo) throw() 00087 : 00088 m_msg(sformat("Bogus %s string: '%s'", 00089 rutz::demangled_name(type), str.c_str())) 00090 { 00091 rutz::error_context::current().prepend_to(m_msg); 00092 00093 if (extrainfo.length() > 0) 00094 m_msg += sformat(" (%s)", extrainfo.c_str()); 00095 } 00096 00097 virtual ~real_conversion_error() throw() {} 00098 00099 virtual const char* what() const throw() 00100 { 00101 return m_msg.c_str(); 00102 } 00103 00104 std::string m_msg; 00105 }; 00106 00107 } 00108 00109 // ###################################################################### 00110 // conversion_error 00111 // ###################################################################### 00112 00113 conversion_error::conversion_error() throw() {} 00114 00115 conversion_error::~conversion_error() throw() {} 00116 00117 void conversion_error::raise_impl(const std::type_info& type, 00118 const std::string& str, 00119 const std::string& extrainfo) 00120 { 00121 throw real_conversion_error(type, str, extrainfo); 00122 } 00123 00124 // ###################################################################### 00125 // converters for basic types 00126 // ###################################################################### 00127 00128 // int 00129 00130 std::string convertToString(const int& val) 00131 { return basictype_to_string(val); } 00132 00133 void convertFromString(const std::string& str, int& val) 00134 { string_to_basictype(str, val); } 00135 00136 // long int 00137 00138 std::string convertToString(const long int& val) 00139 { return basictype_to_string(val); } 00140 00141 void convertFromString(const std::string& str, long int& val) 00142 { string_to_basictype(str, val); } 00143 00144 // long long int 00145 00146 std::string convertToString(const long long int& val) 00147 { return basictype_to_string(val); } 00148 00149 void convertFromString(const std::string& str, long long int& val) 00150 { string_to_basictype(str, val); } 00151 00152 // short int 00153 00154 std::string convertToString(const short int& val) 00155 { return basictype_to_string(val); } 00156 00157 void convertFromString(const std::string& str, short int& val) 00158 { string_to_basictype(str, val); } 00159 00160 // unsigned int 00161 00162 std::string convertToString(const unsigned int& val) 00163 { return basictype_to_string(val); } 00164 00165 void convertFromString(const std::string& str, unsigned int& val) 00166 { string_to_basictype(str, val); } 00167 00168 // unsigned long int 00169 00170 std::string convertToString(const unsigned long int& val) 00171 { return basictype_to_string(val); } 00172 00173 void convertFromString(const std::string& str, unsigned long int& val) 00174 { string_to_basictype(str, val); } 00175 00176 // unsigned long long int 00177 00178 std::string convertToString(const unsigned long long int& val) 00179 { return basictype_to_string(val); } 00180 00181 void convertFromString(const std::string& str, unsigned long long int& val) 00182 { string_to_basictype(str, val); } 00183 00184 // unsigned short int 00185 00186 std::string convertToString(const unsigned short int& val) 00187 { return basictype_to_string(val); } 00188 00189 void convertFromString(const std::string& str, unsigned short int& val) 00190 { string_to_basictype(str, val); } 00191 00192 // unsigned char 00193 00194 std::string convertToString(const unsigned char& val) 00195 { 00196 const int intval = val; 00197 return basictype_to_string(intval); 00198 } 00199 00200 void convertFromString(const std::string& str, unsigned char& val) 00201 { 00202 int intval; 00203 string_to_basictype(str, intval); 00204 00205 if (intval < 0) 00206 conversion_error::raise<unsigned char> 00207 (str, "value too small for range of type"); 00208 else if ((unsigned int) intval > std::numeric_limits<unsigned char>::max()) 00209 conversion_error::raise<unsigned char> 00210 (str, "value too large for range of type"); 00211 00212 val = (unsigned char) intval; 00213 } 00214 00215 // float 00216 00217 std::string convertToString(const float& val) 00218 { return basictype_to_string(val); } 00219 00220 void convertFromString(const std::string& str, float& val) 00221 { string_to_basictype(str, val); } 00222 00223 // double 00224 00225 std::string convertToString(const double& val) 00226 { return basictype_to_string(val); } 00227 00228 void convertFromString(const std::string& str, double& val) 00229 { string_to_basictype(str, val); } 00230 00231 00232 // ###################################################################### 00233 // no-op converters for std::string 00234 // ###################################################################### 00235 00236 std::string convertToString(const std::string& val) 00237 { return val; } 00238 00239 void convertFromString(const std::string& str, std::string& val) 00240 { val = str; } 00241 00242 00243 // ###################################################################### 00244 // converters for bool 00245 // ###################################################################### 00246 00247 std::string convertToString(const bool& val) 00248 { return val ? "true" : "false"; } 00249 00250 void convertFromString(const std::string& str, bool& val) 00251 { 00252 char c = str[0]; 00253 if (c == '1' || c == 't' || c == 'T' || c == 'y' || c == 'Y') 00254 { val = true; } 00255 else if (c == '0' || c == 'f' || c == 'F' || c == 'n' || c == 'N') 00256 { val = false; } 00257 else 00258 conversion_error::raise<bool>(str); 00259 } 00260 00261 00262 // ###################################################################### 00263 // converters for in_addr 00264 // ###################################################################### 00265 00266 std::string convertToString(const in_addr& val) 00267 { 00268 std::stringstream s; 00269 unsigned long int a = val.s_addr; 00270 s<<(a>>24)<<'.'<<((a>>16) & 0xFF)<<'.'<<((a>>8) & 0xFF)<<'.'<<(a & 0xFF); 00271 return s.str(); 00272 } 00273 00274 void convertFromString(const std::string& str, in_addr& val) 00275 { 00276 std::stringstream s; unsigned long int n1 = 300, n2 = 300, n3 = 300, n4=300; 00277 char c; s<<str; s>>n1>>c>>n2>>c>>n3>>c>>n4; 00278 if (n1 == 300 || n2 == 300 || n3 == 300 || n4 == 300) 00279 conversion_error::raise<in_addr>(str); 00280 val.s_addr = (n1 << 24) | (n2 << 16) | (n3 << 8) | n4; 00281 } 00282 00283 // ###################################################################### 00284 // converters for rutz::time 00285 // ###################################################################### 00286 00287 std::string convertToString(const rutz::time& val) 00288 { 00289 const double s = val.sec(); 00290 00291 const int hpart = int(s/(60.0*60.0)); 00292 const int mpart = int((s-hpart*60*60)/60.0); 00293 const double spart = s - hpart*60*60 - mpart*60; 00294 00295 return sformat("%02d:%02d:%06.3f", hpart, mpart, spart); 00296 } 00297 00298 void convertFromString(const std::string& str, rutz::time& val) 00299 { 00300 std::stringstream ss; unsigned long int h = 100, m = 100; float s = 100.0F; 00301 char c; ss<<str; ss>>h>>c>>m>>c>>s; 00302 if (h == 100 || m == 100 || s == 100.0F) conversion_error::raise<rutz::time>(str); 00303 val.reset(h*3600 + m*60 + (unsigned long)s, (unsigned long)((s - int(s)) * 1.0e6F)); 00304 } 00305 00306 00307 // ###################################################################### 00308 /* So things look consistent in everyone's emacs... */ 00309 /* Local Variables: */ 00310 /* indent-tabs-mode: nil */ 00311 /* End: */