common.h

Go to the documentation of this file.
00001 
00005 /* Copyright, 2000 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
00022  */
00023 
00024 #ifndef NL_COMMON_H
00025 #define NL_COMMON_H
00026 
00027 #include "types_nl.h"
00028 
00029 #include <cctype>
00030 #include <cstdio>
00031 #include <cmath>
00032 #include <cstring>
00033 #include <string>
00034 #include <vector>
00035 #include <cfloat>
00036 #include <cstdarg>
00037 #include <cstdlib>
00038 #include <algorithm>
00039 
00040 #ifdef NL_OS_WINDOWS
00041 #   include <process.h>
00042 #   include <intrin.h>
00043 #else
00044 #   include <cmath>
00045 #   include <unistd.h>
00046 #   include <sys/types.h>
00047 #endif
00048 
00049 #include "string_common.h"
00050 
00051 
00053 namespace   NLMISC
00054 {
00055 
00058 #ifdef NL_CPU_INTEL
00059 
00060 inline uint64 rdtsc()
00061 {
00062     uint64 ticks;
00063 #   ifdef NL_OS_WINDOWS
00064 #   ifdef NL_NO_ASM
00065         ticks = uint64(__rdtsc());
00066 #   else
00067         // We should use the intrinsic code now. ticks = uint64(__rdtsc());
00068         __asm   rdtsc
00069         __asm   mov     DWORD PTR [ticks], eax
00070         __asm   mov     DWORD PTR [ticks + 4], edx
00071 #   endif // NL_NO_ASM
00072 #   else
00073         __asm__ volatile(".byte 0x0f, 0x31" : "=a" (ticks.low), "=d" (ticks.high));
00074 #   endif // NL_OS_WINDOWS
00075     return ticks;
00076 }
00077 
00078 #endif  // NL_CPU_INTEL
00079 
00080 
00083 #define     breakable   \
00084     switch(1) case 1: default:
00085 
00086 
00089 const double Pi = 3.1415926535897932384626433832795;
00090 
00091 
00092 // retrieve size of a static array
00093 #define sizeofarray(v) (sizeof(v) / sizeof((v)[0]))
00094 
00097 inline float frand(float mod)
00098 {
00099     double  r = (double) rand();
00100     r/= (double) RAND_MAX;
00101     return (float)(r * mod);
00102 }
00103 
00104 
00107 inline sint fsgn(double f)
00108 {
00109     if(f<0)
00110         return -1;
00111     else if(f>0)
00112         return 1;
00113     else
00114         return 0;
00115 }
00116 
00117 
00120 template<class T>   inline T sqr(const T &v)
00121 {
00122     return v * v;
00123 }
00124 
00125 
00128 template<class T, class U, class V> inline void clamp(T &v, const U &min, const V &max)
00129 {
00130     v = (v < min) ? min : v;
00131     v = (v > max) ? max : v;
00132 }
00133 
00134 
00137 template<class T>   inline T minof(const T& a,  const T& b,  const T& c)
00138     {return std::min(std::min(a,b),c);}
00139 template<class T>   inline T minof(const T& a,  const T& b,  const T& c,  const T& d)
00140     {return std::min(minof(a,b,c),d);}
00141 template<class T>   inline T minof(const T& a,  const T& b,  const T& c,  const T& d,  const T& e)
00142     {return std::min(minof(a,b,c,d),e);}
00143 template<class T>   inline T maxof(const T& a,  const T& b,  const T& c)
00144     {return std::max(std::max(a,b),c);}
00145 template<class T>   inline T maxof(const T& a,  const T& b,  const T& c,  const T& d)
00146     {return std::max(maxof(a,b,c),d);}
00147 template<class T>   inline T maxof(const T& a,  const T& b,  const T& c,  const T& d,  const T& e)
00148     {return std::max(maxof(a,b,c,d),e);}
00149 
00154 template<class T>   inline void contReset (T& a)
00155 {
00156     a.~T();
00157     new (&a) T;
00158 }
00159 
00165 uint            raiseToNextPowerOf2 (uint v);
00166 
00172 uint            getPowerOf2 (uint v);
00173 
00176 bool            isPowerOf2 (sint32 v);
00177 
00178 
00181 inline float    degToRad( float deg )
00182 {
00183     return deg * (float)Pi / 180.0f;
00184 }
00185 
00186 
00189 inline float    radToDeg( float rad )
00190 {
00191     return rad * 180.0f / (float)Pi;
00192 }
00193 
00194 
00197 inline double   isValidDouble (double v)
00198 {
00199 #ifdef NL_OS_WINDOWS
00200     return _finite(v) && !_isnan(v);
00201 #else
00202     return !std::isnan(v) && !std::isinf(v);
00203 #endif
00204 }
00205 
00206 
00211 std::string toLower ( const std::string &str );
00212 void        toLower ( char *str );
00213 char        toLower ( const char ch );  // convert only one character
00214 
00219 std::string toUpper ( const std::string &str);
00220 void        toUpper ( char *str);
00221 
00222 // Remove all the characters <= 32 (tab, space, new line, return, vertical tab etc..) at the beginning and at the end of a string
00223 template <class T> T trim (const T &str)
00224 {
00225     typename T::size_type start = 0;
00226     const typename T::size_type size = str.size();
00227     while (start < size && str[start] <= 32)
00228         start++;
00229     typename T::size_type end = size;
00230     while (end > start && str[end-1] <= 32)
00231         end--;
00232     return str.substr (start, end-start);
00233 }
00234 
00235 // remove spaces at the end of the string
00236 template <class T> T trimRightWhiteSpaces (const T &str)
00237 {
00238     typename T::size_type end = str.size();
00239     while (end > 0 && str[end-1] == ' ')
00240         end--;
00241     return str.substr (0, end);
00242 }
00243 
00245 // ****  DEPRECATED *****: PLEASE DON'T USE THESE METHODS BUT FUNCTIONS ABOVE toLower() and toUpper()
00247 inline std::string      &strlwr ( std::string &str )        { str = toLower(str); return str; }
00248 inline std::string       strlwr ( const std::string &str )  { return toLower(str); }
00249 inline char         *strlwr ( char *str )               { toLower(str); return str; }
00250 inline std::string      &strupr ( std::string &str )        { str = toUpper(str); return str; }
00251 inline std::string       strupr ( const std::string &str )  { return toUpper(str); }
00252 inline char         *strupr ( char *str )               { toUpper(str); return str; }
00253 
00254 
00261 #ifndef NL_OS_WINDOWS
00262 inline int stricmp(const char *lhs, const char *rhs) { return strcasecmp(lhs, rhs); }
00263 inline int strnicmp(const char *lhs, const char *rhs, size_t n) { return strncasecmp(lhs, rhs, n); }
00264 #endif
00265 
00266 inline sint nlstricmp(const char *lhs, const char *rhs) { return stricmp(lhs, rhs); }
00267 inline sint nlstricmp(const std::string &lhs, const std::string &rhs) { return stricmp(lhs.c_str(), rhs.c_str()); }
00268 inline sint nlstricmp(const std::string &lhs, const char *rhs) { return stricmp(lhs.c_str(),rhs); }
00269 inline sint nlstricmp(const char *lhs, const std::string &rhs) { return stricmp(lhs,rhs.c_str()); }
00270 
00273 int     nlfseek64( FILE *stream, sint64 offset, int origin );
00274 
00275 // Retrieve position in a file, same interface as ftell
00276 sint64  nlftell64(FILE *stream);
00277 
00282 class Exception : public std::exception
00283 {
00284 protected:
00285     std::string _Reason;
00286 public:
00287     Exception();
00288     Exception(const std::string &reason);
00289     Exception(const char *format, ...);
00290     virtual ~Exception() throw() {}
00291     virtual const char  *what() const throw();
00292 };
00293 
00294 
00299 void nlSleep( uint32 ms );
00300 
00301 
00303 #ifdef NL_OS_WINDOWS
00304 #   define getpid _getpid
00305 #endif
00306 
00308 uint getThreadId();
00309 
00311 std::string stringFromVector( const std::vector<uint8>& v, bool limited = true );
00312 
00313 
00315 sint64 atoiInt64 (const char *ident, sint64 base = 10);
00316 
00318 void itoaInt64 (sint64 number, char *str, sint64 base = 10);
00319 
00320 
00322 std::string bytesToHumanReadable (const std::string &bytes);
00323 std::string bytesToHumanReadable (uint64 bytes);
00324 
00326 uint32 humanReadableToBytes (const std::string &str);
00327 
00329 std::string secondsToHumanReadable (uint32 time);
00330 
00331 
00333 uint32 fromHumanReadable (const std::string &str);
00334 
00335 
00338 bool launchProgram (const std::string &programName, const std::string &arguments);
00339 
00341 bool killProgram(uint32 pid);
00342 
00344 bool abortProgram(uint32 pid);
00345 
00350 /*acetemplate<class T> std::string toString (const T &t)
00351 {
00352     std::stringstream ss;
00353     ss << t;
00354     return ss.str();
00355 }
00356 */
00357 
00362 /*#ifdef NL_OS_WINDOWS
00363 inline std::string _toString (const char *format, ...)
00364 #else
00365 inline std::string toString (const char *format, ...)
00366 #endif
00367 {
00368     std::string Result;
00369     NLMISC_CONVERT_VARGS (Result, format, NLMISC::MaxCStringSize);
00370     return Result;
00371 }
00372 
00373 #ifdef NL_OS_WINDOWS
00374 CHECK_TYPES(std::string toString, return _toString)
00375 #endif // NL_OS_WINDOWS
00376 
00377 
00378 
00379 #ifdef NL_OS_UNIX
00380 inline std::string toString (const uint8 &t)
00381 {
00382     std::stringstream ss;
00383     ss << (unsigned int)t;
00384     return ss.str();
00385 }
00386 
00387 inline std::string toString (const sint8 &t)
00388 {
00389     std::stringstream ss;
00390     ss << (unsigned int)t;
00391     return ss.str();
00392 }
00393 #endif // NL_OS_UNIX
00394 */
00395 
00401 template <class T> void explode (const T &src, const T &sep, std::vector<T> &res, bool skipEmpty = false)
00402 {
00403     std::string::size_type oldpos = 0, pos;
00404 
00405     res.clear ();
00406 
00407     do
00408     {
00409         pos = src.find (sep, oldpos);
00410         T s;
00411         if(pos == std::string::npos)
00412             s = src.substr (oldpos);
00413         else
00414             s = src.substr (oldpos, (pos-oldpos));
00415 
00416         if (!skipEmpty || !s.empty())
00417             res.push_back (s);
00418 
00419         oldpos = pos+sep.size();
00420     }
00421     while(pos != std::string::npos);
00422 }
00423 
00424 
00425 /* All the code above is used to add our types (uint8, ...) in the stringstream (used by the toString() function).
00426  * So we can use stringstream operator << and >> with all NeL simple types (except for ucchar and ucstring)
00427  */
00428 /*
00429 #ifdef NL_OS_WINDOWS
00430 
00431 #if _MSC_VER < 1300 // visual or older (on visual .NET, we don't need to do that)
00432 
00433 #define NLMISC_ADD_BASIC_ISTREAM_OPERATOR(__type,__casttype) \
00434 template <class _CharT, class _Traits> \
00435 std::basic_istream<_CharT, _Traits>& __cdecl \
00436 operator>>(std::basic_istream<_CharT, _Traits>& __is, __type& __z) \
00437 { \
00438     __casttype __z2 = (__casttype) __z; \
00439     __is.operator>>(__z2); \
00440     __z = (__type) __z2; \
00441     return __is; \
00442 } \
00443  \
00444 template <class _CharT, class _Traits> \
00445 std::basic_ostream<_CharT, _Traits>& __cdecl \
00446 operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __type& __z) \
00447 { \
00448     std::basic_ostringstream<_CharT, _Traits, std::allocator<_CharT> > __tmp; \
00449     __tmp << (__casttype) __z; \
00450     return __os << __tmp.str(); \
00451 }
00452 
00453 NLMISC_ADD_BASIC_ISTREAM_OPERATOR(uint8, unsigned int);
00454 NLMISC_ADD_BASIC_ISTREAM_OPERATOR(sint8, signed int);
00455 NLMISC_ADD_BASIC_ISTREAM_OPERATOR(uint16, unsigned int);
00456 NLMISC_ADD_BASIC_ISTREAM_OPERATOR(sint16, signed int);
00457 NLMISC_ADD_BASIC_ISTREAM_OPERATOR(uint32, unsigned int);
00458 NLMISC_ADD_BASIC_ISTREAM_OPERATOR(sint32, signed int);
00459 
00460 #endif // _MSC_VER < 1300
00461 
00462 
00463 template <class _CharT, class _Traits>
00464 std::basic_istream<_CharT, _Traits>& __cdecl
00465 operator>>(std::basic_istream<_CharT, _Traits>& __is, uint64& __z)
00466 {
00467     __z = 0;
00468     bool neg = false;
00469     char c;
00470     do
00471     {
00472         __is >> c;
00473     }
00474     while (isspace(c));
00475 
00476     if (c == '-')
00477     {
00478         neg = true;
00479         __is >> c;
00480     }
00481 
00482     while (isdigit(c))
00483     {
00484         __z *= 10;
00485         __z += c-'0';
00486         __is >> c;
00487         if (__is.fail())
00488             break;
00489     }
00490 
00491     if (neg) __z = 0;
00492 
00493     return __is;
00494 }
00495 
00496 template <class _CharT, class _Traits>
00497 std::basic_ostream<_CharT, _Traits>& __cdecl
00498 operator<<(std::basic_ostream<_CharT, _Traits>& __os, const uint64& __z)
00499 {
00500     std::basic_ostringstream<_CharT, _Traits, std::allocator<_CharT> > __res;
00501 
00502     if (__z == 0)
00503     {
00504         __res << '0';
00505     }
00506     else
00507     {
00508         std::basic_ostringstream<_CharT, _Traits, std::allocator<_CharT> > __tmp;
00509         uint64  __z2 = __z;
00510         while (__z2 != 0)
00511         {
00512             __tmp << (char)((__z2%10)+'0');
00513             __z2 /= 10;
00514         }
00515 
00516         uint __s = __tmp.str().size();
00517         for (uint i = 0; i < __s; i++)
00518             __res << __tmp.str()[__s - 1 - i];
00519     }
00520     return __os << __res.str();
00521 }
00522 
00523 template <class _CharT, class _Traits>
00524 std::basic_istream<_CharT, _Traits>& __cdecl
00525 operator>>(std::basic_istream<_CharT, _Traits>& __is, sint64& __z)
00526 {
00527     __z = 0;
00528     bool neg = false;
00529     char c;
00530     do
00531     {
00532         __is >> c;
00533     }
00534     while (isspace(c));
00535 
00536     if (c == '-')
00537     {
00538         neg = true;
00539         __is >> c;
00540     }
00541 
00542     while (isdigit(c))
00543     {
00544         __z *= 10;
00545         __z += c-'0';
00546         __is >> c;
00547         if (__is.fail())
00548             break;
00549     }
00550 
00551     if (neg) __z = -__z;
00552 
00553     return __is;
00554 }
00555 
00556 template <class _CharT, class _Traits>
00557 std::basic_ostream<_CharT, _Traits>& __cdecl
00558 operator<<(std::basic_ostream<_CharT, _Traits>& __os, const sint64& __z)
00559 {
00560     std::basic_ostringstream<_CharT, _Traits, std::allocator<_CharT> > __res;
00561 
00562     if (__z == 0)
00563     {
00564         __res << '0';
00565     }
00566     else
00567     {
00568         sint64  __z2 = __z;
00569 
00570         if (__z2 < 0)
00571         {
00572             __res << '-';
00573         }
00574 
00575         std::basic_ostringstream<_CharT, _Traits, std::allocator<_CharT> > __tmp;
00576         while (__z2 != 0)
00577         {
00578             if (__z2 < 0)
00579             {
00580                 __tmp << (char)((-(__z2%10))+'0');
00581             }
00582             else
00583             {
00584                 __tmp << (char)((__z2%10)+'0');
00585             }
00586             __z2 /= 10;
00587         }
00588 
00589         uint __s = __tmp.str().size();
00590         for (uint i = 0; i < __s; i++)
00591             __res << __tmp.str()[__s - 1 - i];
00592     }
00593     return __os << __res.str();
00594 }
00595 
00596 #endif // NL_OS_WINDOWS
00597 */
00598 
00599 class CLog;
00600 
00602 void displayByteBits( uint8 b, uint nbits, sint beginpos, bool displayBegin, NLMISC::CLog *log );
00603 
00605 void displayDwordBits( uint32 b, uint nbits, sint beginpos, bool displayBegin, NLMISC::CLog *log );
00606 
00609 #ifdef NL_OS_WINDOWS
00610 inline int nlisprint(int c)
00611 {
00612     if(c>255||c<0) return 0;
00613     return isprint(c);
00614 }
00615 #else
00616 #define nlisprint isprint
00617 #endif
00618 
00619 // Open an url in a browser
00620 bool openURL (const char *url);
00621 
00622 // Open a document
00623 bool openDoc (const char *document);
00624 
00625 // AntiBug method that return an epsilon if x==0, else x
00626 inline float    favoid0(float x)
00627 {
00628     if(x==0)    return 0.00001f;
00629     return x;
00630 }
00631 inline double   davoid0(double x)
00632 {
00633     if(x==0)    return 0.00001;
00634     return x;
00635 }
00636 // AntiBug method that return 1 if x==0, else x
00637 template<class T>
00638 inline T        iavoid0(T x)
00639 {
00640     if(x==0)    return 1;
00641     return x;
00642 }
00643 
00644 
00645 } // NLMISC
00646 
00647 #endif  // NL_COMMON_H

Generated on Thu Jan 7 08:26:22 2010 for NeL by  doxygen 1.6.1