libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <cstdio> 00013 #include <cstdarg> 00014 00015 #include <iostream> 00016 00017 #include "zypp/base/String.h" 00018 #include "zypp/base/LogTools.h" 00019 00020 using std::string; 00021 00023 namespace zypp 00024 { 00025 00026 namespace str 00027 { 00028 00029 /****************************************************************** 00030 ** 00031 ** FUNCTION NAME : form 00032 ** FUNCTION TYPE : std::string 00033 */ 00034 std::string form( const char * format, ... ) 00035 { 00036 SafeBuf safe; 00037 00038 va_list ap; 00039 va_start( ap, format ); 00040 vasprintf( &safe._buf, format, ap ); 00041 va_end( ap ); 00042 00043 return safe.asString(); 00044 } 00045 00046 /****************************************************************** 00047 ** 00048 ** FUNCTION NAME : strerror 00049 ** FUNCTION TYPE : std::string 00050 */ 00051 std::string strerror( int errno_r ) 00052 { 00053 return form( "(%d)%s", errno_r, ::strerror( errno_r ) ); 00054 } 00055 00056 /****************************************************************** 00057 ** 00058 ** FUNCTION NAME : strToTrue 00059 ** FUNCTION TYPE : bool 00060 */ 00061 bool strToTrue( const C_Str & str ) 00062 { 00063 std::string t( toLower( str ) ); 00064 return( t == "1" 00065 || t == "yes" 00066 || t == "true" 00067 || t == "on" 00068 || t == "+" 00069 || strtonum<long long>( str ) 00070 ); 00071 } 00072 00073 /****************************************************************** 00074 ** 00075 ** FUNCTION NAME : strToFalse 00076 ** FUNCTION TYPE : bool 00077 */ 00078 bool strToFalse( const C_Str & str ) 00079 { 00080 std::string t( toLower( str ) ); 00081 return ! ( t == "0" 00082 || t == "no" 00083 || t == "false" 00084 || t == "off" 00085 || t == "-" 00086 ); 00087 } 00088 00090 // Hexencode 00092 namespace { 00094 inline bool heIsAlNum( char ch ) 00095 { 00096 return ( ( 'a' <= ch && ch <= 'z' ) 00097 ||( 'A' <= ch && ch <= 'Z' ) 00098 ||( '0' <= ch && ch <= '9' ) ); 00099 } 00101 inline int heDecodeCh( char ch ) 00102 { 00103 if ( '0' <= ch && ch <= '9' ) 00104 return( ch - '0' ); 00105 if ( 'A' <= ch && ch <= 'Z' ) 00106 return( ch - 'A' + 10 ); 00107 if ( 'a' <= ch && ch <= 'z' ) 00108 return( ch - 'A' + 10 ); 00109 return -1; 00110 } 00111 } 00112 00113 std::string hexencode( const C_Str & str_r ) 00114 { 00115 static const char *const hdig = "0123456789ABCDEF"; 00116 std::string res; 00117 res.reserve( str_r.size() ); 00118 for ( const char * it = str_r.c_str(); *it; ++it ) 00119 { 00120 if ( heIsAlNum( *it ) ) 00121 { 00122 res += *it; 00123 } 00124 else 00125 { 00126 res += '%'; 00127 res += hdig[(unsigned char)(*it)/16]; 00128 res += hdig[(unsigned char)(*it)%16]; 00129 } 00130 } 00131 return res; 00132 } 00133 00134 std::string hexdecode( const C_Str & str_r ) 00135 { 00136 std::string res; 00137 res.reserve( str_r.size() ); 00138 for_( it, str_r.c_str(), str_r.c_str()+str_r.size() ) 00139 { 00140 if ( *it == '%' ) 00141 { 00142 int d1 = heDecodeCh( *(it+1) ); 00143 if ( d1 != -1 ) 00144 { 00145 int d2 = heDecodeCh( *(it+2) ); 00146 if ( d2 != -1 ) 00147 { 00148 res += (d1<<4)|d2; 00149 it += 2; 00150 continue; 00151 } 00152 } 00153 } 00154 // verbatim if no %XX: 00155 res += *it; 00156 } 00157 return res; 00158 } 00160 00161 /****************************************************************** 00162 ** 00163 ** FUNCTION NAME : toLower 00164 ** FUNCTION TYPE : std::string 00165 */ 00166 std::string toLower( const std::string & s ) 00167 { 00168 if ( s.empty() ) 00169 return s; 00170 00171 std::string ret( s ); 00172 for ( std::string::size_type i = 0; i < ret.length(); ++i ) 00173 { 00174 if ( isupper( ret[i] ) ) 00175 ret[i] = static_cast<char>(tolower( ret[i] )); 00176 } 00177 return ret; 00178 } 00179 00180 /****************************************************************** 00181 ** 00182 ** FUNCTION NAME : toUpper 00183 ** FUNCTION TYPE : std::string 00184 */ 00185 std::string toUpper( const std::string & s ) 00186 { 00187 if ( s.empty() ) 00188 return s; 00189 00190 std::string ret( s ); 00191 for ( std::string::size_type i = 0; i < ret.length(); ++i ) 00192 { 00193 if ( islower( ret[i] ) ) 00194 ret[i] = static_cast<char>(toupper( ret[i] )); 00195 } 00196 return ret; 00197 } 00198 00199 /****************************************************************** 00200 ** 00201 ** FUNCTION NAME : trim 00202 ** FUNCTION TYPE : std::string 00203 */ 00204 std::string trim( const std::string & s, const Trim trim_r ) 00205 { 00206 if ( s.empty() || trim_r == NO_TRIM ) 00207 return s; 00208 00209 std::string ret( s ); 00210 00211 if ( trim_r & L_TRIM ) 00212 { 00213 std::string::size_type p = ret.find_first_not_of( " \t\n" ); 00214 if ( p == std::string::npos ) 00215 return std::string(); 00216 00217 ret = ret.substr( p ); 00218 } 00219 00220 if ( trim_r & R_TRIM ) 00221 { 00222 std::string::size_type p = ret.find_last_not_of( " \t\n" ); 00223 if ( p == std::string::npos ) 00224 return std::string(); 00225 00226 ret = ret.substr( 0, p+1 ); 00227 } 00228 00229 return ret; 00230 } 00231 00232 /****************************************************************** 00233 ** 00234 ** FUNCTION NAME : stripFirstWord 00235 ** FUNCTION TYPE : std::string 00236 */ 00237 std::string stripFirstWord( std::string & line, const bool ltrim_first ) 00238 { 00239 if ( ltrim_first ) 00240 line = ltrim( line ); 00241 00242 if ( line.empty() ) 00243 return line; 00244 00245 std::string ret; 00246 std::string::size_type p = line.find_first_of( " \t" ); 00247 00248 if ( p == std::string::npos ) { 00249 // no ws on line 00250 ret = line; 00251 line.erase(); 00252 } else if ( p == 0 ) { 00253 // starts with ws 00254 // ret remains empty 00255 line = ltrim( line ); 00256 } 00257 else { 00258 // strip word and ltim line 00259 ret = line.substr( 0, p ); 00260 line = ltrim( line.erase( 0, p ) ); 00261 } 00262 return ret; 00263 } 00264 00265 /****************************************************************** 00266 ** 00267 ** FUNCTION NAME : stripLastWord 00268 ** FUNCTION TYPE : std::string 00269 */ 00270 std::string stripLastWord( std::string & line, const bool rtrim_first ) 00271 { 00272 if ( rtrim_first ) 00273 line = rtrim( line ); 00274 00275 if ( line.empty() ) 00276 return line; 00277 00278 std::string ret; 00279 std::string::size_type p = line.find_last_of( " \t" ); 00280 00281 if ( p == std::string::npos ) { 00282 // no ws on line 00283 ret = line; 00284 line.erase(); 00285 } else if ( p == line.size()-1 ) { 00286 // ends with ws 00287 // ret remains empty 00288 line = rtrim( line ); 00289 } 00290 else { 00291 // strip word and rtim line 00292 ret = line.substr( p+1 ); 00293 line = rtrim( line.erase( p ) ); 00294 } 00295 return ret; 00296 } 00297 00298 std::string gsub( const std::string & str_r, const std::string & from_r, const std::string & to_r ) 00299 { 00300 std::string ret( str_r ); 00301 return replaceAll( ret, from_r, to_r ); 00302 } 00303 00304 std::string & replaceAll( std::string & str_r, const std::string & from_r, const std::string & to_r ) 00305 { 00306 std::string::size_type pos = 0; 00307 while ( (pos = str_r.find( from_r, pos )) != std::string::npos ) 00308 { 00309 str_r.replace( pos, from_r.size(), to_r ); 00310 pos += to_r.size(); 00311 00312 if ( pos >= str_r.length() ) 00313 break; 00314 } 00315 return str_r; 00316 } 00317 00318 std::string gsubFun( const std::string & str_r, const std::string & from_r, function<std::string()> to_r ) 00319 { 00320 std::string ret( str_r ); 00321 return replaceAllFun( ret, from_r, to_r ); 00322 } 00323 00324 std::string & replaceAllFun( std::string & str_r, const std::string & from_r, function<std::string()> to_r ) 00325 { 00326 std::string::size_type pos = 0; 00327 while ( (pos = str_r.find( from_r, pos )) != std::string::npos ) 00328 { 00329 std::string to( to_r() ); 00330 str_r.replace( pos, from_r.size(), to ); 00331 pos += to.size(); 00332 00333 if ( pos >= str_r.length() ) 00334 break; 00335 } 00336 return str_r; 00337 } 00338 00339 std::string escape( const C_Str & str_r, const char sep_r ) 00340 { 00341 std::vector<char> buf; 00342 for_( s, str_r.c_str(), s+str_r.size() ) 00343 { 00344 switch ( *s ) 00345 { 00346 case '"': 00347 case '\'': 00348 case '\\': 00349 buf.push_back( '\\' ); 00350 buf.push_back( *s ); 00351 break; 00352 default: 00353 if ( *s == sep_r ) 00354 buf.push_back( '\\' ); 00355 buf.push_back( *s ); 00356 } 00357 } 00358 return std::string( buf.begin(), buf.end() ); 00359 } 00360 00361 std::string getline( std::istream & str, const Trim trim_r ) 00362 { 00363 return trim( receiveUpTo( str, '\n' ), trim_r ); 00364 } 00365 00366 std::string getline( std::istream & str, bool trim_r ) 00367 { 00368 return trim( receiveUpTo( str, '\n' ), trim_r?TRIM:NO_TRIM ); 00369 } 00370 00371 std::string receiveUpTo( std::istream & str, const char delim_r, bool returnDelim_r ) 00372 { 00373 std::ostringstream datas; 00374 do { 00375 char ch; 00376 if ( str.get( ch ) ) 00377 { 00378 if ( ch != delim_r ) 00379 { 00380 datas.put( ch ); 00381 } 00382 else 00383 { 00384 if ( returnDelim_r ) 00385 datas.put( ch ); 00386 break; // --> delimiter found 00387 } 00388 } 00389 else 00390 { 00391 // clear fail bit if we read data before reaching EOF 00392 if ( str.eof() && datas.tellp() ) 00393 str.clear( std::ios::eofbit ); 00394 break; // --> no consumable data. 00395 } 00396 } while ( true ); 00397 return datas.str(); 00398 } 00399 00401 } // namespace str 00404 } // namespace zypp