CppUnit project page CppUnit home page

stringtools.h

Go to the documentation of this file.
00001 #ifndef CPPTL_STRINGTOOLS_H_INCLUDED
00002 # define CPPTL_STRINGTOOLS_H_INCLUDED
00003 
00004 # include <cpptl/conststring.h>
00005 # include <float.h> // toString( double )
00006 # include <stdio.h> // sprintf
00007 
00008 namespace CppTL {
00009 
00010    inline bool isDigit( char c )
00011    {
00012       return unsigned(c) >= '0'  && unsigned(c) <= '9';
00013    }
00014 
00015    inline char digit( unsigned number )
00016    {
00017       static const char *digits = "0123456789";
00018       return digits[number];
00019    }
00020 
00021    inline char hexaDigit( unsigned number )
00022    {
00023       static const char *digit = "0123456789abcdef";
00024       return digit[number];
00025    }
00026 
00027    template<class IntType>
00028    struct SignedPolicy
00029    {
00030       void makePositive( IntType &value )
00031       {
00032          isNegative_ = value < 0;
00033          if ( isNegative_ )
00034             value *= -1;
00035       }
00036 
00037       bool needMinusSign() const
00038       {
00039          return isNegative_;
00040       }
00041 
00042       bool isNegative_;
00043    };
00044 
00045    template<class IntType>
00046    struct UnsignedPolicy
00047    {
00048       void makePositive( IntType & )
00049       {
00050       }
00051 
00052       bool needMinusSign() const
00053       {
00054          return false;
00055       }
00056    };
00057 
00058    template<class IntType, class SignPolicy>
00059    CppTL::ConstString integerToString( IntType v, SignPolicy sign )
00060    {
00061       char buffer[32];
00062       char *current = &buffer[32];
00063       *--current = 0;
00064       if ( v == 0 )
00065          *--current = '0';
00066       else
00067       {
00068          sign.makePositive( v );
00069          while ( v != 0 )
00070          {
00071             *--current = digit( unsigned(v % 10) );
00072             v /= 10;
00073          }
00074          if ( sign.needMinusSign() )
00075             *--current = '-';
00076       }
00077       return current;
00078    }
00079 
00080 
00081    template<class UnsignedIntegerType>
00082    CppTL::ConstString 
00083    integerToHexaString( UnsignedIntegerType value )
00084    {
00085       const int bufferLength = sizeof(UnsignedIntegerType) * 2 + 1;
00086       char buffer[ bufferLength ];
00087       char *current = &buffer[ bufferLength ];
00088       char *end = current;
00089       *--current = 0;
00090       do
00091       {
00092          *--current += hexaDigit( size_type(value & 15) );
00093          value /= 16;
00094       }
00095       while ( value != 0 );
00096 
00097       return CppTL::ConstString( current, end );
00098    }
00099 
00100 
00101    //template<class IntType>
00102    //CppTL::ConstString integerToString( IntType v )
00103    //{
00104    //   CppTL::ConstString s;
00105    //   if ( v == 0 )
00106    //      s += '0';
00107    //   else
00108    //   {
00109    //      bool isSigned = v < 0;
00110    //      if ( isSigned )
00111    //         v *= -1;
00112 
00113    //      while ( v != 0 )
00114    //      {
00115    //         // Thoses cast are necessary to resolve an ambiguity between insert( char *, unsigned, char ) 
00116    //         // and insert( unsigned, unsigned, char) with Sun CC.
00117    //         s.insert( (unsigned int)0, (unsigned int)1, digits[v % 10] ); 
00118    //         v /= 10;
00119    //      }
00120 
00121    //      if ( isSigned )
00122    //         s.insert( 0, "-" );
00123    //   }
00124    //   return s;
00125    //}
00126 
00127    inline CppTL::ConstString toString( char c )
00128    {
00129       return CppTL::ConstString( &c, 1 );
00130    }
00131 
00132    inline CppTL::ConstString toString( int v )
00133    {
00134       return integerToString( v, SignedPolicy<int>() );
00135    }
00136 
00137    inline CppTL::ConstString toString( unsigned int v )
00138    {
00139       return integerToString( v, UnsignedPolicy<unsigned int>() );
00140    }
00141 
00142    inline CppTL::ConstString toString( long v )
00143    {
00144       return integerToString( v, SignedPolicy<long>() );
00145    }
00146 
00147    inline CppTL::ConstString toString( unsigned long v )
00148    {
00149       return integerToString( v, UnsignedPolicy<unsigned long>() );
00150    }
00151 
00152    inline CppTL::ConstString toString( short v )
00153    {
00154       return integerToString( v, SignedPolicy<short>() );
00155    }
00156 
00157    inline CppTL::ConstString toString( unsigned short v )
00158    {
00159       return integerToString( v, UnsignedPolicy<unsigned short>() );
00160    }
00161 
00162 #ifndef CPPTL_NO_INT64
00163 
00164    inline CppTL::ConstString toString( int64_t v )
00165    {
00166       return integerToString( v, SignedPolicy<int64_t>() );
00167    }
00168 
00169    inline CppTL::ConstString toString( uint64_t v )
00170    {
00171       return integerToString( v, UnsignedPolicy<uint64_t>() );
00172    }
00173 #endif
00174 
00175    inline CppTL::ConstString toString( float v )
00176    {
00177 #ifdef FLT_DIG
00178        const int precision = FLT_DIG;
00179 #else
00180        const int precision = 6;
00181 #endif  // #ifdef FLT_DIG
00182        char buffer[128];
00183 #ifdef __STDC_SECURE_LIB__ // Use secure version with visual studio 2005 to avoid warning.
00184        sprintf_s(buffer, sizeof(buffer), "%.*g", precision, v); 
00185 #else 
00186        sprintf(buffer, "%.*g", precision, v); 
00187 #endif
00188        return buffer;
00189    }
00190 
00191    inline CppTL::ConstString toString( double v )
00192    {
00193 #ifdef DBL_DIG
00194        const int precision = DBL_DIG;
00195 #else
00196        const int precision = 15;
00197 #endif  // #ifdef DBL_DIG
00198        char buffer[128];
00199 #ifdef __STDC_SECURE_LIB__ // Use secure version with visual studio 2005 to avoid warning.
00200        sprintf_s(buffer, sizeof(buffer), "%.*g", precision, v); 
00201 #else 
00202        sprintf(buffer, "%.*g", precision, v); 
00203 #endif
00204        return buffer;
00205    }
00206 
00207    inline CppTL::ConstString toString( long double v )
00208    {
00209 #ifdef DBL_DIG
00210        const int precision = DBL_DIG;
00211 #else
00212        const int precision = 15;
00213 #endif  // #ifdef DBL_DIG
00214        char buffer[128];
00215 #ifdef __STDC_SECURE_LIB__ // Use secure version with visual studio 2005 to avoid warning.
00216        sprintf_s(buffer, sizeof(buffer), "%.*g", precision, v); 
00217 #else 
00218        sprintf(buffer, "%.*g", precision, v); 
00219 #endif
00220        return buffer;
00221    }
00222 
00223    inline CppTL::ConstString toString( bool v )
00224    {
00225       return v ? "true" : "false";
00226    }
00227 
00228 
00229    inline CppTL::ConstString toHexaString( unsigned int v )
00230    {
00231       return integerToHexaString( v );
00232    }
00233 
00234 
00235 #ifndef CPPTL_NO_INT64
00236    inline CppTL::ConstString toHexaString( uint64_t v )
00237    {
00238       return integerToHexaString( v );
00239    }
00240 #endif
00241 
00242 
00243 inline void
00244 escapeControl( char c, CppTL::StringBuffer &escaped, const char *newLineEscape = "\\n" )
00245 {
00246    switch ( c )
00247    {
00248    case '\n':
00249       escaped += newLineEscape;
00250       break;
00251    case '\t':
00252       escaped += CppTL::ConstCharView( "\\t", 2 );
00253       break;
00254    case '\r':
00255       escaped += CppTL::ConstCharView( "\\r", 2 );
00256       break;
00257    case '\v':
00258       escaped += CppTL::ConstCharView( "\\v", 2 );
00259       break;
00260    default:
00261       {
00262          char hexa[2];
00263          hexa[0] = hexaDigit( (c >> 4) & 15 );
00264          hexa[1] = hexaDigit( c & 15 );
00265          escaped += CppTL::ConstCharView( "\\x", 2 ) 
00266                     + ConstCharView( hexa, hexa + sizeof(hexa) );
00267       }
00268       break;
00269    }
00270 }
00271 
00272 
00273 inline void
00274 escape( char c, CppTL::StringBuffer &escaped, const char *newLineEscape = "\\n" )
00275 {
00276    if ( c >=0  &&  c < 32 )
00277       escapeControl( c, escaped, newLineEscape );
00278    else if ( c == '\\' )
00279       escaped += CppTL::ConstCharView( "\\\\", 2 );
00280    escaped += CppTL::ConstCharView( &c, 1 );
00281 }
00282 
00283 
00284 // need to expose some of those utility functions...
00285 inline void
00286 escapeRange( const char *first,
00287              const char *last, 
00288              CppTL::StringBuffer &escaped, 
00289              const char *newLineEscape = "\\n" )
00290 {
00291    while ( first != last )
00292       escape( *first++, escaped, newLineEscape );
00293 }
00294 
00295 inline void
00296 escape( const CppTL::ConstString &text, 
00297         CppTL::StringBuffer &escaped, 
00298         const char *newLineEscape = "\\n" )
00299 {
00300    escapeRange( text.c_str(), text.c_str() + text.length(), escaped );
00301 }
00302 
00303 
00304 inline CppTL::ConstString 
00305 quoteStringRange( const char *first,
00306                   const char *last,
00307                   const char *newLineEscape = "\\n" )
00308 {
00309    CppTL::StringBuffer escaped( size_type((last-first) * 1.2) + 64 );
00310    escaped += CppTL::ConstCharView( "\"", 1 );
00311    escapeRange(first, last, escaped, newLineEscape );
00312    escaped += CppTL::ConstCharView( "\"", 1 );
00313    return escaped;
00314 }
00315 
00316 
00317 inline CppTL::ConstString 
00318 quoteString( const CppTL::ConstString &text, 
00319              const char *newLineEscape = "\\n" )
00320 {
00321    return quoteStringRange( text.c_str(), text.c_str() + text.length() );
00322 }
00323 
00324 
00325 inline CppTL::ConstString 
00326 quoteMultiLineStringRange( const char *first, 
00327                            const char *last )
00328 {
00329    return quoteStringRange( first, last, "\\n\n" );
00330 }
00331 
00332 
00333 inline CppTL::ConstString 
00334 quoteMultiLineString( const CppTL::ConstString &str )
00335 {
00336    return quoteString( str, "\\n\n" );
00337 }
00338 
00339 
00340 } // namespace CppTL
00341 
00342 #endif // CPPTL_STRINGTOOLS_H_INCLUDED
00343 

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers