1/* -*-c++-*- */ 2/* osgEarth - Geospatial SDK for OpenSceneGraph 3 * Copyright 2019 Pelican Mapping 4 * http://osgearth.org 5 * 6 * osgEarth is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/> 18 */ 19#ifndef OSGEARTH_STRING_UTILS_H 20#define OSGEARTH_STRING_UTILS_H 1 21 22#include <osgEarth/Common> 23#include <osg/Vec3> 24#include <osg/Vec3d> 25#include <osg/Vec4> 26#include <osg/Vec4ub> 27#include <string> 28#include <algorithm> 29#include <vector> 30#include <sstream> 31#include <locale> 32#include <iomanip> 33#include <map> 34#include <set> 35#include <ctype.h> 36 37namespace osgEarth 38{ 39 extern OSGEARTH_EXPORT const std::string EMPTY_STRING; 40 41 typedef std::vector<std::string> StringVector; 42 typedef std::set<std::string> StringSet; 43 44 /** Replaces all the instances of "pattern" with "replacement" in "in_out" */ 45 extern OSGEARTH_EXPORT std::string& replaceIn( 46 std::string& in_out, 47 const std::string& pattern, 48 const std::string& replacement ); 49 50 /** Replaces all the instances of "pattern" with "replacement" in "in_out" (case-insensitive) */ 51 extern OSGEARTH_EXPORT std::string& ciReplaceIn( 52 std::string& in_out, 53 const std::string& pattern, 54 const std::string& replacement ); 55 56 /** 57 * Trims whitespace from the ends of a string. 58 */ 59 extern OSGEARTH_EXPORT std::string trim( const std::string& in ); 60 61 /** 62 * Trims whitespace from the ends of a string; in-place modification on the string to reduce string copies. 63 */ 64 extern OSGEARTH_EXPORT void trim2( std::string& str ); 65 66 //! Removes leading and trailing whitespace, and replaces all other 67 //! whitespace with single spaces 68 extern OSGEARTH_EXPORT std::string trimAndCompress(const std::string& in); 69 70 /** 71 * True is "ref" starts with "pattern" 72 */ 73 extern OSGEARTH_EXPORT bool startsWith( 74 const std::string& ref, 75 const std::string& pattern, 76 bool caseSensitive =true, 77 const std::locale& locale =std::locale() ); 78 79 /** 80 * True is "ref" ends with "pattern" 81 */ 82 extern OSGEARTH_EXPORT bool endsWith( 83 const std::string& ref, 84 const std::string& pattern, 85 bool caseSensitive =true, 86 const std::locale& locale =std::locale() ); 87 88 /** 89 * Case-insensitive compare 90 */ 91 extern OSGEARTH_EXPORT bool ciEquals( 92 const std::string& lhs, 93 const std::string& rhs, 94 const std::locale& local = std::locale() ); 95 96 /** 97 * Case-insensitive STL comparator 98 */ 99 struct OSGEARTH_EXPORT CIStringComp { 100 bool operator()(const std::string& lhs, const std::string& rhs) const; 101 }; 102 103 104 extern OSGEARTH_EXPORT std::string joinStrings( const StringVector& input, char delim ); 105 106 /** Returns a lower-case version of the input string. */ 107 extern OSGEARTH_EXPORT std::string toLower( const std::string& input ); 108 109 /** Parses a color string in the form "255 255 255 255" (r g b a [0..255]) into an OSG color. */ 110 extern OSGEARTH_EXPORT osg::Vec4ub stringToColor(const std::string& str, osg::Vec4ub default_value); 111 112 /** Creates a string in the form "255 255 255 255" (r g b a [0..255]) from a color */ 113 extern OSGEARTH_EXPORT std::string colorToString( const osg::Vec4ub& c ); 114 115 /** Converts a string to a vec3f */ 116 extern OSGEARTH_EXPORT osg::Vec3f stringToVec3f( const std::string& str, const osg::Vec3f& default_value ); 117 118 /** Converts a vec3f to a string */ 119 extern OSGEARTH_EXPORT std::string vec3fToString( const osg::Vec3f& v ); 120 121 /** Parses an HTML color ("#rrggbb" or "#rrggbbaa") into an OSG color. */ 122 extern OSGEARTH_EXPORT osg::Vec4f htmlColorToVec4f( const std::string& html ); 123 124 /** Makes an HTML color ("#rrggbb" or "#rrggbbaa") from an OSG color. */ 125 extern OSGEARTH_EXPORT std::string vec4fToHtmlColor( const osg::Vec4f& c ); 126 127 /** Makes a valid filename out of a string */ 128 extern OSGEARTH_EXPORT std::string toLegalFileName( const std::string& input, bool allowSubdir=false ); 129 130 /** Generates a hashed integer for a string (poor man's MD5) */ 131 extern OSGEARTH_EXPORT unsigned hashString( const std::string& input ); 132 133 /** Same as hashString but returns a string value. */ 134 extern OSGEARTH_EXPORT std::string hashToString(const std::string& input); 135 136 /** 137 * Gets the total number of seconds formatted as H:M:S 138 */ 139 extern OSGEARTH_EXPORT std::string prettyPrintTime( double seconds ); 140 141 /** 142 * Gets a pretty printed version of the given size in MB. 143 */ 144 extern OSGEARTH_EXPORT std::string prettyPrintSize( double mb ); 145 146 //------------------------------------------------------------------------ 147 // conversion templates 148 149 // converts a string to primitive using serialization 150 template<typename T> inline T 151 as( const std::string& str, const T& default_value ) 152 { 153 T temp = default_value; 154 std::istringstream strin( str ); 155 if ( !strin.eof() ) strin >> temp; 156 return temp; 157 } 158 159 // template specialization for integers (to handle hex) 160#define AS_INT_DEC_OR_HEX(TYPE) \ 161 template<> inline TYPE \ 162 as< TYPE >(const std::string& str, const TYPE & dv) { \ 163 TYPE temp = dv; \ 164 std::istringstream strin( trim(str) ); \ 165 if ( !strin.eof() ) { \ 166 if ( str.length() >= 2 && str[0] == '0' && str[1] == 'x' ) { \ 167 strin.seekg( 2 ); \ 168 strin >> std::hex >> temp; \ 169 } \ 170 else { \ 171 strin >> temp; \ 172 } \ 173 } \ 174 return temp; \ 175 } 176 177 AS_INT_DEC_OR_HEX(int) 178 AS_INT_DEC_OR_HEX(unsigned) 179 AS_INT_DEC_OR_HEX(short) 180 AS_INT_DEC_OR_HEX(unsigned short) 181 AS_INT_DEC_OR_HEX(long) 182 AS_INT_DEC_OR_HEX(unsigned long) 183 184 // template specialization for a bool 185 template<> inline bool 186 as<bool>( const std::string& str, const bool& default_value ) 187 { 188 std::string temp = toLower(str); 189 return 190 temp == "true" || temp == "yes" || temp == "on" ? true : 191 temp == "false" || temp == "no" || temp == "off" ? false : 192 default_value; 193 } 194 195 template<> inline osg::Vec3f 196 as<osg::Vec3f>( const std::string& str, const osg::Vec3f& default_value ) 197 { 198 return stringToVec3f(str, default_value); 199 } 200 201 // template specialization for string 202 template<> inline std::string 203 as<std::string>( const std::string& str, const std::string& default_value ) 204 { 205 return str; 206 } 207 208 // snips a substring and parses it. 209 template<typename T> inline bool 210 as(const std::string& in, unsigned start, unsigned len, T default_value) 211 { 212 std::string buf; 213 std::copy( in.begin()+start, in.begin()+start+len, std::back_inserter(buf) ); 214 return as<T>(buf, default_value); 215 } 216 217 // converts a primitive to a string 218 // TODO: precision?? 219 template<typename T> inline std::string 220 toString(const T& value) 221 { 222 std::stringstream out; 223 //out << std::setprecision(20) << std::fixed << value; 224 out << std::setprecision(20) << value; 225 std::string outStr; 226 outStr = out.str(); 227 return outStr; 228 } 229 230 // template speciallization for a bool to print out "true" or "false" 231 template<> inline std::string 232 toString<bool>(const bool& value) 233 { 234 return value ? "true" : "false"; 235 } 236 237 template<> inline std::string 238 toString<osg::Vec3f>(const osg::Vec3f& value) 239 { 240 return vec3fToString(value); 241 } 242 243 /** 244 * Assembles and returns an inline string using a stream-like << operator. 245 * Example: 246 * std::string str = Stringify() << "Hello, world " << variable; 247 */ 248 struct Stringify 249 { 250 operator std::string () const 251 { 252 std::string result; 253 result = buf.str(); 254 return result; 255 } 256 257 template<typename T> 258 Stringify& operator << (const T& val) { buf << val; return (*this); } 259 260 Stringify& operator << (const Stringify& val) { buf << (std::string)val; return (*this); } 261 262 protected: 263 std::stringstream buf; 264 }; 265 266 template<> inline 267 Stringify& Stringify::operator << <bool>(const bool& val) { buf << (val ? "true" : "false"); return (*this); } 268 269 template<> inline 270 Stringify& Stringify::operator << <osg::Vec3f>(const osg::Vec3f& val) { 271 buf << val.x() << " " << val.y() << " " << val.z(); return (*this); } 272 273 template<> inline 274 Stringify& Stringify::operator << <osg::Vec3d>(const osg::Vec3d& val ) { 275 buf << val.x() << " " << val.y() << " " << val.z(); return (*this); } 276 277 template<> inline 278 Stringify& Stringify::operator << <osg::Vec4f>(const osg::Vec4f& val) { 279 buf << val.r() << " " << val.g() << " " << val.b() << " " << val.a(); return (*this); } 280 281 /** 282 * Splits a string up into a vector of strings based on a set of 283 * delimiters, quotes, and rules. 284 */ 285 class OSGEARTH_EXPORT StringTokenizer 286 { 287 public: 288 StringTokenizer( const std::string& delims =" \t\r\n", const std::string& quotes ="'\"" ); 289 290 StringTokenizer( 291 const std::string& input, StringVector& output, 292 const std::string& delims =" \t\r\n", const std::string& quotes ="'\"", 293 bool keepEmpties =true, bool trimTokens =true); 294 295 void tokenize( const std::string& input, StringVector& output ) const; 296 297 bool& keepEmpties() { return _allowEmpties; } 298 299 bool& trimTokens() { return _trimTokens; } 300 301 void addDelim( char delim, bool keepAsToken =false ); 302 303 void addDelims( const std::string& delims, bool keepAsTokens =false ); 304 305 void addQuote( char delim, bool keepInToken =false ); 306 307 void addQuotes( const std::string& delims, bool keepInTokens =false ); 308 309 private: 310 typedef std::map<char,bool> TokenMap; 311 TokenMap _delims; 312 TokenMap _quotes; 313 bool _allowEmpties; 314 bool _trimTokens; 315 }; 316} 317 318#endif // OSGEARTH_STRING_UTILS_H 319 320