osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarth/StringUtils

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #ifndef OSGEARTH_STRING_UTILS_H
00020 #define OSGEARTH_STRING_UTILS_H 1
00021 
00022 #include <osgEarth/Common>
00023 #include <osg/Vec4>
00024 #include <osg/Vec4ub>
00025 #include <string>
00026 #include <algorithm>
00027 #include <vector>
00028 #include <sstream>
00029 #include <iomanip>
00030 #include <map>
00031 
00032 namespace osgEarth
00033 {
00034     typedef std::vector<std::string> StringVector;
00035 
00037     static std::string&
00038     replaceIn( std::string& s, const std::string& sub, const std::string& other)
00039     {
00040         if ( sub.empty() ) return s;
00041         size_t b=0;
00042         for( ; ; )
00043         {
00044             b = s.find( sub, b );
00045             if ( b == s.npos ) break;
00046             s.replace( b, sub.size(), other );
00047             b += other.size();
00048         }
00049         return s;
00050     }
00051 
00057     static
00058     std::string trim( const std::string& in )
00059     {
00060         std::string whitespace (" \t\f\v\n\r");
00061         std::string str = in;
00062         std::string::size_type pos = str.find_last_not_of( whitespace );
00063         if(pos != std::string::npos) {
00064             str.erase(pos + 1);
00065             pos = str.find_first_not_of( whitespace );
00066             if(pos != std::string::npos) str.erase(0, pos);
00067         }
00068         else str.erase(str.begin(), str.end());
00069         return str;
00070     }
00071 
00075     static
00076     bool startsWith( const std::string& ref, const std::string& pattern )
00077     {
00078         return ref.find( pattern ) == 0;
00079     }
00080 
00084     static
00085     bool endsWith( const std::string& ref, const std::string& pattern )
00086     {
00087         return ref.find( pattern ) == ref.length()-pattern.length();
00088     }
00089 
00094     class OSGEARTH_EXPORT StringTokenizer
00095     {
00096     public:
00097         StringTokenizer( const std::string& delims =" \t\r\n", const std::string& quotes ="'\"" );
00098 
00099         StringTokenizer(
00100             const std::string& input, StringVector& output,
00101             const std::string& delims =" \t\r\n", const std::string& quotes ="'\"",
00102             bool keepEmpties =true, bool trimTokens =true);
00103 
00104         void tokenize( const std::string& input, StringVector& output ) const;
00105 
00106         bool& keepEmpties() { return _allowEmpties; }
00107 
00108         bool& trimTokens() { return _trimTokens; }
00109 
00110         void addDelim( char delim, bool keepAsToken =false );
00111 
00112         void addDelims( const std::string& delims, bool keepAsTokens =false );
00113 
00114         void addQuote( char delim, bool keepInToken =false );
00115 
00116         void addQuotes( const std::string& delims, bool keepInTokens =false );
00117         
00118     private:
00119         typedef std::map<char,bool> TokenMap;
00120         TokenMap _delims;
00121         TokenMap _quotes;
00122         bool     _allowEmpties;
00123         bool     _trimTokens;
00124     };
00125 
00126     static std::string
00127     joinStrings( const StringVector& input, char delim )
00128     {
00129         std::stringstream buf;
00130         for( StringVector::const_iterator i = input.begin(); i != input.end(); ++i )
00131         {
00132             buf << *i;
00133             if ( (i+1) != input.end() ) buf << delim;
00134         }
00135         std::string result = buf.str();
00136         return result;
00137     }
00138 
00140     static std::string
00141     toLower( const std::string& input )
00142     {
00143         std::string output = input;
00144         std::transform( output.begin(), output.end(), output.begin(), ::tolower );
00145         return output;
00146     }
00147 
00149     static osg::Vec4ub
00150     stringToColor(const std::string& str, osg::Vec4ub default_value)
00151     {
00152         osg::Vec4ub color = default_value;
00153         std::istringstream strin(str);
00154         int r, g, b, a;
00155         if (strin >> r && strin >> g && strin >> b && strin >> a)
00156         {
00157             color.r() = (unsigned char)r;
00158             color.g() = (unsigned char)g;
00159             color.b() = (unsigned char)b;
00160             color.a() = (unsigned char)a;
00161         }
00162         return color;
00163     }
00164 
00166     static std::string
00167     colorToString( const osg::Vec4ub& c )
00168     {
00169         std::stringstream ss;
00170         ss << (int)c.r() << " " << (int)c.g() << " " << (int)c.b() << " " << (int)c.a();
00171         std::string ssStr;
00172         ssStr = ss.str();
00173         return ssStr;
00174     }
00175 
00177     static osg::Vec3f
00178     stringToVec3f( const std::string& str, const osg::Vec3f& default_value )
00179     {
00180         std::stringstream buf(str);
00181         osg::Vec3f out = default_value;
00182         buf >> out.x();
00183         if ( !buf.eof() ) {
00184             buf >> out.y() >> out.z();
00185         }
00186         else {
00187             out.y() = out.x();
00188             out.z() = out.x();
00189         }
00190         return out;
00191     }
00192 
00194     static std::string
00195     vec3fToString( const osg::Vec3f& v )
00196     {
00197         std::stringstream buf;
00198         buf << std::setprecision(6)
00199             << v.x() << " " << v.y() << " " << v.z()
00200             << std::endl;
00201         std::string result;
00202         result = buf.str();
00203         return result;
00204     }
00205 
00207     static osg::Vec4f
00208     htmlColorToVec4f( const std::string& html )
00209     {
00210         std::string t = html;
00211         std::transform( t.begin(), t.end(), t.begin(), ::tolower );
00212         osg::Vec4ub c(0,0,0,255);
00213         if ( t.length() >= 7 ) {
00214             c.r() |= t[1]<='9' ? (t[1]-'0')<<4 : (10+(t[1]-'a'))<<4;
00215             c.r() |= t[2]<='9' ? (t[2]-'0')    : (10+(t[2]-'a'));
00216             c.g() |= t[3]<='9' ? (t[3]-'0')<<4 : (10+(t[3]-'a'))<<4;
00217             c.g() |= t[4]<='9' ? (t[4]-'0')    : (10+(t[4]-'a'));
00218             c.b() |= t[5]<='9' ? (t[5]-'0')<<4 : (10+(t[5]-'a'))<<4;
00219             c.b() |= t[6]<='9' ? (t[6]-'0')    : (10+(t[6]-'a'));
00220             if ( t.length() == 9 ) {
00221                 c.a() = 0;
00222                 c.a() |= t[7]<='9' ? (t[7]-'0')<<4 : (10+(t[7]-'a'))<<4;
00223                 c.a() |= t[8]<='9' ? (t[8]-'0')    : (10+(t[8]-'a'));
00224             }
00225         }
00226         return osg::Vec4f( ((float)c.r())/255.0f, ((float)c.g())/255.0f, ((float)c.b())/255.0f, ((float)c.a())/255.0f );
00227     }
00228 
00230     static std::string
00231     vec4fToHtmlColor( const osg::Vec4f& c )
00232     {
00233         std::stringstream buf;
00234         buf << "#";
00235         buf << std::hex << std::setw(2) << std::setfill('0') << (int)(c.r()*255.0f);
00236         buf << std::hex << std::setw(2) << std::setfill('0') << (int)(c.g()*255.0f);
00237         buf << std::hex << std::setw(2) << std::setfill('0') << (int)(c.b()*255.0f);
00238         if ( c.a() < 1.0f )
00239             buf << std::hex << std::setw(2) << std::setfill('0') << (int)(c.a()*255.0f);
00240         std::string ssStr = buf.str();
00241         return ssStr;
00242     }
00243 
00245     static unsigned int
00246     hashString( const std::string& input )
00247     {
00248             const unsigned int m = 0x5bd1e995;
00249             const int r = 24;
00250         unsigned int len = input.length();
00251         const char* data = input.c_str();
00252             unsigned int h = m ^ len; // using "m" as the seed.
00253 
00254             while(len >= 4)
00255             {
00256                     unsigned int k = *(unsigned int *)data;
00257                     k *= m; 
00258                     k ^= k >> r; 
00259                     k *= m;                     
00260                     h *= m; 
00261                     h ^= k;
00262                     data += 4;
00263                     len -= 4;
00264             }
00265         
00266             switch(len)
00267             {
00268             case 3: h ^= data[2] << 16;
00269             case 2: h ^= data[1] << 8;
00270             case 1: h ^= data[0];
00271                     h *= m;
00272             };
00273 
00274             h ^= h >> 13;
00275             h *= m;
00276             h ^= h >> 15;
00277 
00278             return h;
00279     }
00280     
00281     //------------------------------------------------------------------------
00282     // conversion templates
00283 
00284     // converts a string to primitive using serialization
00285     template<typename T> inline T
00286     as( const std::string& str, const T& default_value )
00287     {
00288         T temp = default_value;
00289         std::istringstream strin( str );
00290         if ( !strin.eof() ) strin >> temp;
00291         return temp;
00292     }
00293 
00294     // template specialization for a bool
00295     template<> inline bool
00296     as<bool>( const std::string& str, const bool& default_value )
00297     {
00298         std::string temp = str;
00299         std::transform( temp.begin(), temp.end(), temp.begin(), ::tolower );
00300         return
00301             temp == "true" || temp == "yes" || temp == "on" ? true :
00302             temp == "false" || temp == "no" || temp == "off" ? false :
00303             default_value;
00304     }
00305 
00306     template<> inline osg::Vec3f
00307     as<osg::Vec3f>( const std::string& str, const osg::Vec3f& default_value )
00308     {
00309         return stringToVec3f(str, default_value);
00310     }
00311 
00312     // template specialization for string
00313     template<> inline std::string
00314     as<std::string>( const std::string& str, const std::string& default_value )
00315     {
00316         return str;
00317     }
00318 
00319     // converts a primitive to a string
00320     // TODO: precision??
00321     template<typename T> inline std::string
00322     toString(const T& value)
00323     {
00324         std::stringstream out;
00325                 out << std::setprecision(20) << std::fixed << value;
00326         std::string outStr;
00327         outStr = out.str();
00328         return outStr;
00329     }
00330 
00331     // template speciallization for a bool to print out "true" or "false"
00332     template<> inline std::string
00333     toString<bool>(const bool& value)
00334     {
00335         return value ? "true" : "false";
00336     }
00337 
00338     template<> inline std::string
00339     toString<osg::Vec3f>(const osg::Vec3f& value)
00340     {
00341         return vec3fToString(value);
00342     }
00343 
00344     struct Stringify
00345     {
00346         operator std::string () const
00347         {
00348             std::string result;
00349             result = buf.str();
00350             return result;
00351         }
00352 
00353         Stringify& operator << (bool val) { buf << val; return (*this); }
00354         Stringify& operator << (short val) { buf << val; return (*this); }
00355         Stringify& operator << (unsigned short val) { buf << val; return (*this); }
00356         Stringify& operator << (int val) { buf << val; return (*this); }
00357         Stringify& operator << (unsigned int val) { buf << val; return (*this); }
00358         Stringify& operator << (long val) { buf << val; return (*this); }
00359         Stringify& operator << (unsigned long val) { buf << val; return (*this); }
00360         Stringify& operator << (float val) { buf << val; return (*this); }
00361         Stringify& operator << (double val) { buf << val; return (*this); }
00362         Stringify& operator << (long double val) { buf << val; return (*this); }
00363         Stringify& operator << (const void* val) { buf << val; return (*this); }
00364         Stringify& operator << (char val) { buf << val; return (*this); }
00365         Stringify& operator << (signed char val) { buf << val; return (*this); }
00366         Stringify& operator << (unsigned char val) { buf << val; return (*this); }
00367         Stringify& operator << (const char* val) { buf << val; return (*this); }
00368         Stringify& operator << (const signed char* val) { buf << val; return (*this); }
00369         Stringify& operator << (const unsigned char* val) { buf << val; return (*this); }
00370         Stringify& operator << (const std::string& val) { buf << val; return (*this); }
00371         Stringify& operator << (std::streambuf* val) { buf << val; return (*this); }
00372         Stringify& operator << (std::ostream& (*val)(std::ostream&)) { buf << val; return (*this); }
00373         Stringify& operator << (std::ios& (*val)(std::ostream&)) { buf << val; return (*this); }
00374         Stringify& operator << (std::ios_base& (*val)(std::ios_base&)) { buf << val; return (*this); }
00375 
00376     protected:
00377         std::stringstream buf;
00378     };
00379 }
00380 
00381 #endif // OSGEARTH_STRING_UTILS_H
00382 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines