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 
00019 using std::string;
00020 
00022 namespace zypp
00023 { 
00024 
00025   namespace str
00026   { 
00027 
00028     /******************************************************************
00029      **
00030      **      FUNCTION NAME : form
00031      **      FUNCTION TYPE : std::string
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      **      FUNCTION NAME : strerror
00048      **      FUNCTION TYPE : std::string
00049     */
00050     std::string strerror( int errno_r )
00051     {
00052       return form( "(%d)%s", errno_r, ::strerror( errno_r ) );
00053     }
00054 
00055     /******************************************************************
00056      **
00057      **      FUNCTION NAME : strToTrue
00058      **      FUNCTION TYPE : bool
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      **      FUNCTION NAME : strToFalse
00075      **      FUNCTION TYPE : bool
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     // Hexencode
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         // verbatim if no %XX:
00154         res += *it;
00155       }
00156       return res;
00157     }
00159 
00160     /******************************************************************
00161      **
00162      **      FUNCTION NAME : toLower
00163      **      FUNCTION TYPE : std::string
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      **      FUNCTION NAME : toUpper
00182      **      FUNCTION TYPE : std::string
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      **      FUNCTION NAME : trim
00201      **      FUNCTION TYPE : std::string
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     **  FUNCTION NAME : stripFirstWord
00234     **  FUNCTION TYPE : std::string
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         // no ws on line
00249         ret = line;
00250         line.erase();
00251       } else if ( p == 0 ) {
00252         // starts with ws
00253         // ret remains empty
00254         line = ltrim( line );
00255       }
00256       else {
00257         // strip word and ltim line
00258         ret = line.substr( 0, p );
00259         line = ltrim( line.erase( 0, p ) );
00260       }
00261       return ret;
00262     }
00263 
00264     /******************************************************************
00265     **
00266     **  FUNCTION NAME : stripLastWord
00267     **  FUNCTION TYPE : std::string
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         // no ws on line
00282         ret = line;
00283         line.erase();
00284       } else if ( p == line.size()-1 ) {
00285         // ends with ws
00286         // ret remains empty
00287         line = rtrim( line );
00288       }
00289       else {
00290         // strip word and rtim line
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     **      FUNCTION NAME : getline
00367     **      FUNCTION TYPE : std::string
00368     **
00369     **      DESCRIPTION :
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 ); // always writes '\0' terminated
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   } // namespace str
00400 } // namespace zypp
Generated on Fri Mar 2 09:45:51 2012 for libzypp by  doxygen 1.6.3