String.cc

Go to the documentation of this file.
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     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;      // --> delimiter found
00388           }
00389         }
00390         else
00391         {
00392           // clear fail bit if we read data before reaching EOF
00393           if ( str.eof() && datas.tellp() )
00394             str.clear( std::ios::eofbit );
00395           break;        // --> no consumable data.
00396         }
00397       } while ( true );
00398       return datas.str();
00399     }
00400 
00402   } // namespace str
00405 } // namespace zypp

doxygen