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
00019 using std::string;
00020
00022 namespace zypp
00023 {
00024
00025 namespace str
00026 {
00027
00028
00029
00030
00031
00032
00033 std::string form( const char * format, ... )
00034 {
00035 SafeBuf safe;
00036
00037 va_list ap;
00038 va_start( ap, format );
00039 vasprintf( &safe._buf, format, ap );
00040 va_end( ap );
00041
00042 return safe.asString();
00043 }
00044
00045
00046
00047
00048
00049
00050 std::string strerror( int errno_r )
00051 {
00052 return form( "(%d)%s", errno_r, ::strerror( errno_r ) );
00053 }
00054
00055
00056
00057
00058
00059
00060 bool strToTrue( const C_Str & str )
00061 {
00062 std::string t( toLower( str ) );
00063 return( t == "1"
00064 || t == "yes"
00065 || t == "true"
00066 || t == "on"
00067 || t == "+"
00068 || strtonum<long long>( str )
00069 );
00070 }
00071
00072
00073
00074
00075
00076
00077 bool strToFalse( const C_Str & str )
00078 {
00079 std::string t( toLower( str ) );
00080 return ! ( t == "0"
00081 || t == "no"
00082 || t == "false"
00083 || t == "off"
00084 || t == "-"
00085 );
00086 }
00087
00089
00091 namespace {
00093 inline bool heIsAlNum( char ch )
00094 {
00095 return ( ( 'a' <= ch && ch <= 'z' )
00096 ||( 'A' <= ch && ch <= 'Z' )
00097 ||( '0' <= ch && ch <= '9' ) );
00098 }
00100 inline int heDecodeCh( char ch )
00101 {
00102 if ( '0' <= ch && ch <= '9' )
00103 return( ch - '0' );
00104 if ( 'A' <= ch && ch <= 'Z' )
00105 return( ch - 'A' + 10 );
00106 if ( 'a' <= ch && ch <= 'z' )
00107 return( ch - 'A' + 10 );
00108 return -1;
00109 }
00110 }
00111
00112 std::string hexencode( const C_Str & str_r )
00113 {
00114 static const char *const hdig = "0123456789ABCDEF";
00115 std::string res;
00116 res.reserve( str_r.size() );
00117 for ( const char * it = str_r.c_str(); *it; ++it )
00118 {
00119 if ( heIsAlNum( *it ) )
00120 {
00121 res += *it;
00122 }
00123 else
00124 {
00125 res += '%';
00126 res += hdig[(unsigned char)(*it)/16];
00127 res += hdig[(unsigned char)(*it)%16];
00128 }
00129 }
00130 return res;
00131 }
00132
00133 std::string hexdecode( const C_Str & str_r )
00134 {
00135 std::string res;
00136 res.reserve( str_r.size() );
00137 for_( it, str_r.c_str(), str_r.c_str()+str_r.size() )
00138 {
00139 if ( *it == '%' )
00140 {
00141 int d1 = heDecodeCh( *(it+1) );
00142 if ( d1 != -1 )
00143 {
00144 int d2 = heDecodeCh( *(it+2) );
00145 if ( d2 != -1 )
00146 {
00147 res += (d1<<4)|d2;
00148 it += 2;
00149 continue;
00150 }
00151 }
00152 }
00153
00154 res += *it;
00155 }
00156 return res;
00157 }
00159
00160
00161
00162
00163
00164
00165 std::string toLower( const std::string & s )
00166 {
00167 if ( s.empty() )
00168 return s;
00169
00170 std::string ret( s );
00171 for ( std::string::size_type i = 0; i < ret.length(); ++i )
00172 {
00173 if ( isupper( ret[i] ) )
00174 ret[i] = static_cast<char>(tolower( ret[i] ));
00175 }
00176 return ret;
00177 }
00178
00179
00180
00181
00182
00183
00184 std::string toUpper( const std::string & s )
00185 {
00186 if ( s.empty() )
00187 return s;
00188
00189 std::string ret( s );
00190 for ( std::string::size_type i = 0; i < ret.length(); ++i )
00191 {
00192 if ( islower( ret[i] ) )
00193 ret[i] = static_cast<char>(toupper( ret[i] ));
00194 }
00195 return ret;
00196 }
00197
00198
00199
00200
00201
00202
00203 std::string trim( const std::string & s, const Trim trim_r )
00204 {
00205 if ( s.empty() || trim_r == NO_TRIM )
00206 return s;
00207
00208 std::string ret( s );
00209
00210 if ( trim_r & L_TRIM )
00211 {
00212 std::string::size_type p = ret.find_first_not_of( " \t\n" );
00213 if ( p == std::string::npos )
00214 return std::string();
00215
00216 ret = ret.substr( p );
00217 }
00218
00219 if ( trim_r & R_TRIM )
00220 {
00221 std::string::size_type p = ret.find_last_not_of( " \t\n" );
00222 if ( p == std::string::npos )
00223 return std::string();
00224
00225 ret = ret.substr( 0, p+1 );
00226 }
00227
00228 return ret;
00229 }
00230
00231
00232
00233
00234
00235
00236 std::string stripFirstWord( std::string & line, const bool ltrim_first )
00237 {
00238 if ( ltrim_first )
00239 line = ltrim( line );
00240
00241 if ( line.empty() )
00242 return line;
00243
00244 std::string ret;
00245 std::string::size_type p = line.find_first_of( " \t" );
00246
00247 if ( p == std::string::npos ) {
00248
00249 ret = line;
00250 line.erase();
00251 } else if ( p == 0 ) {
00252
00253
00254 line = ltrim( line );
00255 }
00256 else {
00257
00258 ret = line.substr( 0, p );
00259 line = ltrim( line.erase( 0, p ) );
00260 }
00261 return ret;
00262 }
00263
00264
00265
00266
00267
00268
00269 std::string stripLastWord( std::string & line, const bool rtrim_first )
00270 {
00271 if ( rtrim_first )
00272 line = rtrim( line );
00273
00274 if ( line.empty() )
00275 return line;
00276
00277 std::string ret;
00278 std::string::size_type p = line.find_last_of( " \t" );
00279
00280 if ( p == std::string::npos ) {
00281
00282 ret = line;
00283 line.erase();
00284 } else if ( p == line.size()-1 ) {
00285
00286
00287 line = rtrim( line );
00288 }
00289 else {
00290
00291 ret = line.substr( p+1 );
00292 line = rtrim( line.erase( p ) );
00293 }
00294 return ret;
00295 }
00296
00297 string gsub(const string& sData, const string& sFrom, const string& sTo)
00298 {
00299 string sNew;
00300 sNew.reserve(sData.size());
00301
00302 if (! sData.empty())
00303 {
00304 string::size_type frLen = sFrom.length();
00305 string::size_type loc = 0;
00306 string::size_type oldLoc = 0;
00307
00308 while (string::npos != (loc = sData.find(sFrom, loc)))
00309 {
00310 sNew.append(sData,oldLoc,loc-oldLoc);
00311 sNew.append(sTo);
00312 loc += frLen;
00313 oldLoc = loc;
00314 if (loc >= sData.length())
00315 break;
00316 }
00317 if (oldLoc!=sData.size())
00318 sNew.append(sData,oldLoc,sData.size()-oldLoc);
00319 }
00320
00321 return sNew;
00322 }
00323
00324 string & replaceAll(string & str, const string & from, const string & to)
00325 {
00326 string::size_type pos = 0;
00327 while((pos = str.find(from, pos)) != string::npos)
00328 {
00329 str.replace(pos, from.size(), to);
00330 pos += to.size();
00331
00332 if (pos >= str.length())
00333 break;
00334 }
00335 return str;
00336 }
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
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 static inline std::string _getline( std::istream & str, const Trim trim_r )
00372 {
00373 const unsigned tmpBuffLen = 1024;
00374 char tmpBuff[tmpBuffLen];
00375
00376 std::string ret;
00377 do {
00378 str.clear();
00379 str.getline( tmpBuff, tmpBuffLen );
00380 ret += tmpBuff;
00381 } while( str.rdstate() == std::ios::failbit );
00382
00383 return trim( ret, trim_r );
00384 }
00385
00386 std::string getline( std::istream & str, const Trim trim_r )
00387 {
00388 return _getline(str, trim_r);
00389 }
00390
00391 std::string getline( std::istream & str, bool trim )
00392 {
00393 return _getline(str, trim?TRIM:NO_TRIM);
00394 }
00395
00397 }
00400 }