String.cc
Go to the documentation of this file.00001
00002
00003
00004
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
00032
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
00049
00050
00051 std::string strerror( int errno_r )
00052 {
00053 return form( "(%d)%s", errno_r, ::strerror( errno_r ) );
00054 }
00055
00056
00057
00058
00059
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
00076
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
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
00155 res += *it;
00156 }
00157 return res;
00158 }
00160
00161
00162
00163
00164
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
00183
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
00202
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
00235
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
00250 ret = line;
00251 line.erase();
00252 } else if ( p == 0 ) {
00253
00254
00255 line = ltrim( line );
00256 }
00257 else {
00258
00259 ret = line.substr( 0, p );
00260 line = ltrim( line.erase( 0, p ) );
00261 }
00262 return ret;
00263 }
00264
00265
00266
00267
00268
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
00283 ret = line;
00284 line.erase();
00285 } else if ( p == line.size()-1 ) {
00286
00287
00288 line = rtrim( line );
00289 }
00290 else {
00291
00292 ret = line.substr( p+1 );
00293 line = rtrim( line.erase( p ) );
00294 }
00295 return ret;
00296 }
00297
00298 string gsub(const string& sData, const string& sFrom, const string& sTo)
00299 {
00300 string sNew;
00301 sNew.reserve(sData.size());
00302
00303 if (! sData.empty())
00304 {
00305 string::size_type frLen = sFrom.length();
00306 string::size_type loc = 0;
00307 string::size_type oldLoc = 0;
00308
00309 while (string::npos != (loc = sData.find(sFrom, loc)))
00310 {
00311 sNew.append(sData,oldLoc,loc-oldLoc);
00312 sNew.append(sTo);
00313 loc += frLen;
00314 oldLoc = loc;
00315 if (loc >= sData.length())
00316 break;
00317 }
00318 if (oldLoc!=sData.size())
00319 sNew.append(sData,oldLoc,sData.size()-oldLoc);
00320 }
00321
00322 return sNew;
00323 }
00324
00325 string & replaceAll(string & str, const string & from, const string & to)
00326 {
00327 string::size_type pos = 0;
00328 while((pos = str.find(from, pos)) != string::npos)
00329 {
00330 str.replace(pos, from.size(), to);
00331 pos += to.size();
00332
00333 if (pos >= str.length())
00334 break;
00335 }
00336 return str;
00337 }
00338
00339
00340 std::string escape( const C_Str & str_r, const char sep_r )
00341 {
00342 std::vector<char> buf;
00343 for_( s, str_r.c_str(), s+str_r.size() )
00344 {
00345 switch ( *s )
00346 {
00347 case '"':
00348 case '\'':
00349 case '\\':
00350 buf.push_back( '\\' );
00351 buf.push_back( *s );
00352 break;
00353 default:
00354 if ( *s == sep_r )
00355 buf.push_back( '\\' );
00356 buf.push_back( *s );
00357 }
00358 }
00359 return std::string( buf.begin(), buf.end() );
00360 }
00361
00362 std::string getline( std::istream & str, const Trim trim_r )
00363 {
00364 return trim( receiveUpTo( str, '\n' ), trim_r );
00365 }
00366
00367 std::string getline( std::istream & str, bool trim_r )
00368 {
00369 return trim( receiveUpTo( str, '\n' ), trim_r?TRIM:NO_TRIM );
00370 }
00371
00372 std::string receiveUpTo( std::istream & str, const char delim_r, bool returnDelim_r )
00373 {
00374 std::ostringstream datas;
00375 do {
00376 char ch;
00377 if ( str.get( ch ) )
00378 {
00379 if ( ch != delim_r )
00380 {
00381 datas.put( ch );
00382 }
00383 else
00384 {
00385 if ( returnDelim_r )
00386 datas.put( ch );
00387 break;
00388 }
00389 }
00390 else
00391 {
00392
00393 if ( str.eof() && datas.tellp() )
00394 str.clear( std::ios::eofbit );
00395 break;
00396 }
00397 } while ( true );
00398 return datas.str();
00399 }
00400
00402 }
00405 }