arguments.cpp

Go to the documentation of this file.
00001 
00008 /**************************************************************************
00009 
00010    begin                : Sat Sep 09 2007
00011    copyright            : (C) 2007 by Ewald Arnold
00012    email                : log4sendpp at ewald-arnold dot de
00013 
00014    This program is free software; you can redistribute it and/or modify
00015    it under the terms of the GNU Lesser General Public License as
00016    published by the Free Software Foundation; either version 2 of the License,
00017    or (at your option) any later version.
00018 
00019    This program is distributed in the hope that it will be useful,
00020    but WITHOUT ANY WARRANTY; without even the implied warranty of
00021    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022    GNU General Public License for more details.
00023 
00024    You should have received a copy of the GNU Lesser General Public License
00025    along with this program; if not, write to the Free Software
00026    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00027 
00028  **/
00029 
00030 
00032 #define LOG4SENDPP_NEED_EXPORTS
00033 #include <log4sendpp/log4sendpp.h>  // always first header
00034 
00035 #include <cstdio>
00036 #include <cctype>
00037 #include <limits>
00038 
00039 #include <log4sendpp/arguments.h>
00040 #include <log4sendpp/exception.h>
00041 
00042 
00043 LOG4SENDPP_NS_START
00044 
00045 LOG4SENDPP_ANON_NS_START
00046 
00050 template <typename T, typename uT>
00051 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string) number_stpl( T n, unsigned base )
00052 {
00053   if ( base < 2 || base > 36 )
00054   {
00055     LOG4SENDPP_STD_NS::string fmt = "Conversion of T to String: base %1 not allowed";
00056     fmt << number( ( uT ) base, 10 );
00057     LOG4SENDPP_THROW(LOG4SENDPP_NS::Exception( __LINE__, __FILE__, fmt ));
00058 #ifdef LOG4SENDPP_NO_EXCEPTIONS
00059     return "";
00060 #endif
00061   }
00062 
00063   char charbuf[ sizeof(T) * 65 * sizeof( char ) ];
00064   char *buf = ( char* ) charbuf;
00065   char *p = &buf[ sizeof(T) * 64 ];
00066   *p = '\0' ;
00067   int len = 0;
00068   bool neg;
00069   if ( n < 0 )
00070   {
00071     neg = true;
00072 #ifdef HAVE_LIMITS
00073     if ( n == LOG4SENDPP_STD_NS::numeric_limits<T>::min() )
00074 #else
00075     if ( n == INT_MIN )
00076 #endif
00077     {
00078       LOG4SENDPP_STD_NS::string s1, s2;
00079       s1 = number( n / ( T ) base, base );
00080 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00081       s2 = number( ( unsigned T ) ( -( n + ( T ) base ) ) % base, base );
00082 #else
00083       s2 = number( ( -( n + ( T ) base ) ) % base, base );
00084 #endif
00085       return s1 + s2;
00086     }
00087     n = -n;
00088   }
00089   else
00090   {
00091     neg = false;
00092   }
00093 
00094   do
00095   {
00096     *--p = "0123456789abcdefghijklmnopqrstuvwxyz"[ ( ( int ) ( n % base ) ) ];
00097     n /= base;
00098     len++;
00099   }
00100   while ( n );
00101 
00102   if ( neg )
00103   {
00104     *--p =  '-';
00105     len++;
00106   }
00107   return p;
00108 }
00109 
00110 LOG4SENDPP_NS_END
00111 
00112 
00113 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string) number( long n, unsigned base )
00114 {
00115   return number_stpl<long, unsigned long>(n, base);
00116 }
00117 
00118 
00119 #ifndef UPS_NO_LONG_LONG
00120 
00121 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string) number( long long n, unsigned base )
00122 {
00123   return number_stpl<long long, unsigned long long>(n, base);
00124 }
00125 
00126 #endif
00127 
00128 LOG4SENDPP_ANON_NS_START
00129 
00133 template <typename T>
00134 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string) number_utpl(T n, unsigned base )
00135 {
00136   if ( base < 2 || base > 36 )
00137   {
00138     LOG4SENDPP_STD_NS::string fmt = "Conversion of unsigned T to String: base %1 not allowed";
00139     fmt << number( ( T ) base, 10 );
00140     LOG4SENDPP_THROW(LOG4SENDPP_NS::Exception( __LINE__, __FILE__, fmt ));
00141 #ifdef LOG4SENDPP_NO_EXCEPTIONS
00142     return "";
00143 #endif
00144   }
00145 
00146   char charbuf[ sizeof(T) * 65 * sizeof( char ) ];
00147   char *buf = ( char* ) charbuf;
00148   char *p = &buf[ sizeof(T) * 64 ];
00149   int len = 0;
00150   *p =  '\0';
00151   do
00152   {
00153     *--p = "0123456789abcdefghijklmnopqrstuvwxyz" [ ( ( int ) ( n % base ) ) ];
00154     n /= base;
00155     len++;
00156   }
00157   while ( n );
00158 
00159   return p;
00160 }
00161 
00162 LOG4SENDPP_NS_END
00163 
00164 
00165 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string) number( unsigned long n, unsigned base )
00166 {
00167   return number_utpl<unsigned long>(n, base);
00168 }
00169 
00170 
00171 #ifndef UPS_NO_LONG_LONG
00172 
00173 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string) number( unsigned long long n, unsigned base )
00174 {
00175   return number_utpl<unsigned long long>(n, base);
00176 }
00177 
00178 #endif
00179 
00180 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string) number( double n, unsigned prec )
00181 {
00182   if ( prec > 99 )
00183     prec = 99;
00184 
00185   char format[ 20 ];
00186   char buf[ 120 ];
00187   char *fs = format;
00188 
00189   *fs++ = '%';
00190   if ( prec != 0 )
00191   {
00192     *fs++ = '.';
00193     if ( prec >= 10 )
00194     {
00195       *fs++ = prec / 10 + '0';
00196       *fs++ = prec % 10 + '0';
00197     }
00198     else
00199       *fs++ = prec + '0';      //   "%.<prec>lg"
00200     *fs++ = 'l';
00201   }
00202   *fs++ = 'g';
00203   *fs = '\0';
00204 #if defined HAVE_SPRINTF_S
00205   sprintf_s( buf, format, n );
00206 #else
00207   LOG4SENDPP_STD_NS::sprintf( buf, format, n );
00208 #endif
00209 
00210 #ifdef LOG4SENDPP_UNICODE
00211   return LOG4SENDPP_NS::getUnicode( buf );
00212 #else
00213   return LOG4SENDPP_STD_NS::string( buf );
00214 #endif
00215 }
00216 
00217 
00221 static bool findArg( LOG4SENDPP_STD_NS::string &fmt, int& pos, int& len )
00222 {
00223   char lowest = 0;
00224   for ( unsigned int i = 0; i < fmt.length(); i++ )
00225   {
00226     if ( fmt[ i ] ==  '%' && i + 1 < fmt.length() )
00227     {
00228       char dig = fmt[ i + 1 ];
00229       if ( dig >=  '0' && dig <=  '9' )
00230       {
00231         if ( !lowest || dig < lowest )
00232         {
00233           lowest = dig;
00234           pos = i;
00235           len = 2;
00236         }
00237       }
00238     }
00239   }
00240   return lowest != 0;
00241 }
00242 
00243 
00244 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) replaceFormatterString(LOG4SENDPP_STD_NS::string &formatter, const LOG4SENDPP_STD_NS::string &repdata)
00245 {
00246   int pos, len;
00247 
00248   if ( !findArg(formatter, pos, len ) )
00249   {
00250     LOG4SENDPP_THROW(LOG4SENDPP_NS::Exception(__LINE__, __FILE__, "No %-placeholder found to insert \'"
00251                                                              + repdata
00252                                                              + "\' into \'"
00253                                                              + formatter
00254                                                              + "\'"));
00255 #ifdef LOG4SENDPP_NO_EXCEPTIONS
00256     return formatter;
00257 #endif
00258   }
00259 
00260   else
00261     formatter.replace( pos, len, repdata);
00262 
00263   return formatter;
00264 }
00265 
00266 
00270 static LOG4SENDPP_STD_NS::string charToReadable(unsigned x)
00271 {
00272   LOG4SENDPP_STD_NS::string text;
00273 #ifndef LOG4SENDPP_MAKE_CHAR_READABLE
00274   text += x;
00275 #else
00276 #if (defined (_MSC_VER) && (_MSC_VER <= 1300)) || (defined (__GNUC__) && (__GNUC__ < 3))
00277   if (!isalnum(x))
00278 #else
00279   if (!LOG4SENDPP_STD_NS::isalnum(x))
00280 #endif
00281   {
00282     text += "0x" + number((unsigned long)x, 16);
00283   }
00284   else
00285   {
00286     text += "{\"";
00287     text += x;
00288     text += "\", ";
00289     text += "0x" + number((unsigned long)x, 16);
00290     text += "}";
00291   }
00292 #endif
00293   return text;
00294 }
00295 
00296 
00297 LOG4SENDPP_NS_END
00298 
00299 
00300 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const int &repdata )
00301 {
00302   formatter << LOG4SENDPP_NS::number( ( long ) repdata );
00303   return formatter;
00304 }
00305 
00306 
00307 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const bool &repdata )
00308 {
00309   formatter << (repdata ? "true"
00310                         : "false" );
00311   return formatter;
00312 }
00313 
00314 
00315 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const unsigned int &repdata )
00316 {
00317   formatter << LOG4SENDPP_NS::number( ( unsigned long ) repdata );
00318   return formatter;
00319 }
00320 
00321 
00322 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const unsigned long &repdata )
00323 {
00324   formatter << LOG4SENDPP_NS::number( repdata );
00325   return formatter;
00326 }
00327 
00328 
00329 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const signed char &repdata )
00330 {
00331   formatter << LOG4SENDPP_NS::charToReadable(repdata);
00332   return formatter;
00333 }
00334 
00335 
00336 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const char &repdata )
00337 {
00338   formatter << LOG4SENDPP_NS::charToReadable(repdata);
00339   return formatter;
00340 }
00341 
00342 
00343 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const unsigned char &repdata )
00344 {
00345   formatter << LOG4SENDPP_NS::charToReadable(repdata);
00346   return formatter;
00347 }
00348 
00349 
00350 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const char *repdata )
00351 {
00352   formatter << LOG4SENDPP_STD_NS::string(repdata);
00353   return formatter;
00354 }
00355 
00356 
00357 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const float &repdata )
00358 {
00359   formatter << LOG4SENDPP_NS::number( repdata );
00360   return formatter;
00361 }
00362 
00363 
00364 #ifdef LOG4SENDPP_UNICODE
00365 
00366 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const wchar_t &repdata )
00367 {
00368   formatter << LOG4SENDPP_NS::charToReadable(repdata);
00369   return formatter;
00370 }
00371 
00372 
00373 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const wchar_t * repdata )
00374 {
00375   formatter << LOG4SENDPP_STD_NS::string(repdata);
00376   return formatter;
00377 }
00378 
00379 #endif
00380 
00381 
00382 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const long &repdata )
00383 {
00384   formatter << LOG4SENDPP_NS::number( repdata );
00385   return formatter;
00386 }
00387 
00388 
00389 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const double &repdata )
00390 {
00391   formatter << LOG4SENDPP_NS::number( repdata );
00392   return formatter;
00393 }
00394 
00395 
00396 #ifdef LOG4SENDPP_UNICODE
00397 
00398 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << ( LOG4SENDPP_STD_NS::string &formatter, const LOG4SENDPP_STD_NS::string &str )
00399 {
00400   formatter << LOG4SENDPP_NS::getUnicode( str );
00401   return formatter;
00402 }
00403 
00404 #else
00405 
00406 // LOG4SENDPP_STD_NS::string & operator << (LOG4SENDPP_STD_NS::string &formatter, const LOG4SENDPP_STL::basic_string<wchar_t> &str)
00407 // {
00408 //   formatter << LOG4SENDPP_NS::getLatin1(str);
00409 //   return formatter;
00410 // }
00411 
00412 #endif
00413 
00414 
00415 LOG4SENDPP_API_IMPL(LOG4SENDPP_STD_NS::string &) operator << (LOG4SENDPP_STD_NS::string &formatter, const LOG4SENDPP_STD_NS::string &repdata)
00416 {
00417   return LOG4SENDPP_NS::replaceFormatterString(formatter, repdata);
00418 }
00419 
00420 

Generated on Sat Nov 24 14:41:22 2007 for log4sendpp by  doxygen 1.5.3