Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

RageUtil.h

Go to the documentation of this file.
00001 /* RageUtil - Miscellaneous helper macros and functions. */ 00002 00003 #ifndef RAGE_UTIL_H 00004 #define RAGE_UTIL_H 00005 00006 #define SAFE_DELETE(p) { delete (p); (p)=NULL; } 00007 #define SAFE_DELETE_ARRAY(p) { delete[] (p); (p)=NULL; } 00008 00009 #define ZERO(x) memset(&x, 0, sizeof(x)) 00010 #define COPY(a,b) { ASSERT(sizeof(a)==sizeof(b)); memcpy(&(a), &(b), sizeof(a)); } 00011 #define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0])) 00012 00013 /* Common harmless mismatches. All min(T,T) and max(T,T) cases are handled 00014 * by the generic template we get from <algorithm>. */ 00015 inline float min(float a, int b) { return a < b? a:b; } 00016 inline float min(int a, float b) { return a < b? a:b; } 00017 inline float max(float a, int b) { return a > b? a:b; } 00018 inline float max(int a, float b) { return a > b? a:b; } 00019 inline unsigned long min(unsigned int a, unsigned long b) { return a < b? a:b; } 00020 inline unsigned long min(unsigned long a, unsigned int b) { return a < b? a:b; } 00021 inline unsigned long max(unsigned int a, unsigned long b) { return a > b? a:b; } 00022 inline unsigned long max(unsigned long a, unsigned int b) { return a > b? a:b; } 00023 00024 /* Traditional defines. Only use this if you absolutely need 00025 * a constant value. */ 00026 #ifndef MAX 00027 #define MAX(a,b) (((a) > (b)) ? (a) : (b)) 00028 #endif 00029 00030 #ifndef MIN 00031 #define MIN(a,b) (((a) < (b)) ? (a) : (b)) 00032 #endif 00033 00034 #define clamp(val,low,high) ( max( (low), min((val),(high)) ) ) 00035 00036 // Scales x so that l1 corresponds to l2 and h1 corresponds to h2. Does not modify x, MUST assign the result to something! 00037 // Do the multiply before the divide to that integer scales have more precision. 00038 #define SCALE(x, l1, h1, l2, h2) (((x) - (l1)) * ((h2) - (l2)) / ((h1) - (l1)) + (l2)) 00039 00040 inline bool CLAMP(int &x, int l, int h) 00041 { 00042 if (x > h) { x = h; return true; } 00043 else if (x < l) { x = l; return true; } 00044 return false; 00045 } 00046 inline bool CLAMP(float &x, float l, float h) 00047 { 00048 if (x > h) { x = h; return true; } 00049 else if (x < l) { x = l; return true; } 00050 return false; 00051 } 00052 00053 inline void wrap( int &x, int n) 00054 { 00055 if (x<0) 00056 x += ((-x/n)+1)*n; 00057 x %= n; 00058 } 00059 inline void wrap( float &x, float n) 00060 { 00061 if (x<0) 00062 x += truncf(((-x/n)+1))*n; 00063 x = fmodf(x,n); 00064 } 00065 00066 /* 00067 * We only have unsigned swaps; byte swapping a signed value doesn't make sense. 00068 * 00069 * Platform-specific, optimized versions are defined in arch_setup, with the names 00070 * ArchSwap32, ArchSwap24, and ArchSwap16; we define them to their real names here, 00071 * to force inclusion of this file when swaps are in use (to prevent different dependencies 00072 * on different systems). 00073 */ 00074 #ifdef HAVE_BYTE_SWAPS 00075 #define Swap32 ArchSwap32 00076 #define Swap24 ArchSwap24 00077 #define Swap16 ArchSwap16 00078 #else 00079 inline uint32_t Swap32( uint32_t n ) 00080 { 00081 return (n >> 24) | 00082 ((n >> 8) & 0x0000FF00) | 00083 ((n << 8) & 0x00FF0000) | 00084 (n << 24); 00085 } 00086 00087 inline uint32_t Swap24( uint32_t n ) 00088 { 00089 return Swap32(n) >> 8; // xx223344 -> 443322xx -> 00443322 00090 } 00091 00092 inline uint16_t Swap16( uint16_t n ) 00093 { 00094 return (n >> 8) | (n << 8); 00095 } 00096 #endif 00097 00098 #if defined(ENDIAN_LITTLE) 00099 inline uint32_t Swap32LE( uint32_t n ) { return n; } 00100 inline uint32_t Swap24LE( uint32_t n ) { return n; } 00101 inline uint16_t Swap16LE( uint16_t n ) { return n; } 00102 inline uint32_t Swap32BE( uint32_t n ) { return Swap32( n ); } 00103 inline uint32_t Swap24BE( uint32_t n ) { return Swap24( n ); } 00104 inline uint16_t Swap16BE( uint16_t n ) { return Swap16( n ); } 00105 #else 00106 inline uint32_t Swap32BE( uint32_t n ) { return n; } 00107 inline uint32_t Swap24BE( uint32_t n ) { return n; } 00108 inline uint16_t Swap16BE( uint16_t n ) { return n; } 00109 inline uint32_t Swap32LE( uint32_t n ) { return Swap32( n ); } 00110 inline uint32_t Swap24LE( uint32_t n ) { return Swap24( n ); } 00111 inline uint16_t Swap16LE( uint16_t n ) { return Swap16( n ); } 00112 #endif 00113 00114 extern int randseed; 00115 00116 float RandomFloat( int &seed ); 00117 00118 inline float RandomFloat() 00119 { 00120 return RandomFloat( randseed ); 00121 } 00122 00123 // Returns a float between dLow and dHigh inclusive 00124 inline float RandomFloat(float fLow, float fHigh) 00125 { 00126 return SCALE( RandomFloat(), 0.0f, 1.0f, fLow, fHigh ); 00127 } 00128 00129 // Returns an integer between nLow and nHigh inclusive 00130 inline int RandomInt(int nLow, int nHigh) 00131 { 00132 return int( RandomFloat() * (nHigh - nLow + 1) + nLow ); 00133 } 00134 00135 /* Alternative: */ 00136 class RandomGen 00137 { 00138 int seed; 00139 00140 public: 00141 RandomGen( unsigned long seed = 0 ); 00142 int operator() ( int maximum = INT_MAX-1 ); 00143 }; 00144 00145 00146 // Simple function for generating random numbers 00147 inline float randomf( const float low=-1.0f, const float high=1.0f ) 00148 { 00149 return RandomFloat( low, high ); 00150 } 00151 00152 /* return f rounded to the nearest multiple of fRoundInterval */ 00153 inline float Quantize( const float f, const float fRoundInterval ) 00154 { 00155 return int( (f + fRoundInterval/2)/fRoundInterval ) * fRoundInterval; 00156 } 00157 00158 inline int Quantize( const int i, const int iRoundInterval ) 00159 { 00160 return int( (i + iRoundInterval/2)/iRoundInterval ) * iRoundInterval; 00161 } 00162 00163 /* return f truncated to the nearest multiple of fTruncInterval */ 00164 inline float ftruncf( const float f, const float fTruncInterval ) 00165 { 00166 return int( (f)/fTruncInterval ) * fTruncInterval; 00167 } 00168 00169 /* Return i rounded up to the nearest multiple of iInterval. */ 00170 inline int QuantizeUp( int i, int iInterval ) 00171 { 00172 return int( (i+iInterval-1)/iInterval ) * iInterval; 00173 } 00174 00175 // Move val toward other_val by to_move. 00176 void fapproach( float& val, float other_val, float to_move ); 00177 00178 /* Return a positive x mod y. */ 00179 float fmodfp(float x, float y); 00180 00181 int power_of_two(int input); 00182 bool IsAnInt( const CString &s ); 00183 bool IsHexVal( const CString &s ); 00184 float HHMMSSToSeconds( const CString &sHMS ); 00185 CString SecondsToHHMMSS( float fSecs ); 00186 CString SecondsToMMSSMsMs( float fSecs ); 00187 CString SecondsToMMSSMsMsMs( float fSecs ); 00188 CString PrettyPercent( float fNumerator, float fDenominator ); 00189 inline CString PrettyPercent( int fNumerator, int fDenominator ) { return PrettyPercent( float(fNumerator), float(fDenominator) ); } 00190 CString Commify( int iNum ); 00191 00192 00193 struct tm GetLocalTime(); 00194 00195 CString ssprintf( const char *fmt, ...) PRINTF(1,2); 00196 CString vssprintf( const char *fmt, va_list argList ); 00197 00198 #ifdef WIN32 00199 CString hr_ssprintf( int hr, const char *fmt, ...); 00200 CString werr_ssprintf( int err, const char *fmt, ...); 00201 CString ConvertWstringToACP( wstring s ); 00202 CString ConvertUTF8ToACP( CString s ); 00203 #endif 00204 00205 // Splits a Path into 4 parts (Directory, Drive, Filename, Extention). Supports UNC path names. 00206 /* If Path is a directory (eg. c:\games\stepmania"), append a slash so the last 00207 * element will end up in Dir, not FName: "c:\games\stepmania\". */ 00208 void splitpath( const CString &Path, CString &Dir, CString &Filename, CString &Ext ); 00209 00210 CString SetExtension( const CString &path, const CString &ext ); 00211 CString GetExtension( const CString &sPath ); 00212 00213 typedef int longchar; 00214 extern const wchar_t INVALID_CHAR; 00215 00216 int utf8_get_char_len( char p ); 00217 bool utf8_to_wchar( const CString &s, unsigned &start, wchar_t &ch ); 00218 bool utf8_to_wchar_ec( const CString &s, unsigned &start, wchar_t &ch ); 00219 void wchar_to_utf8( wchar_t ch, CString &out ); 00220 wchar_t utf8_get_char( const CString &s ); 00221 bool utf8_is_valid( const CString &s ); 00222 void utf8_remove_bom( CString &s ); 00223 00224 CString WStringToCString(const wstring &str); 00225 CString WcharToUTF8( wchar_t c ); 00226 wstring CStringToWstring(const CString &str); 00227 00228 // Splits a CString into an CStringArray according the Delimitor. 00229 void split( const CString &Source, const CString &Delimitor, CStringArray& AddIt, const bool bIgnoreEmpty = true ); 00230 void split( const wstring &Source, const wstring &Delimitor, vector<wstring> &AddIt, const bool bIgnoreEmpty = true ); 00231 00232 /* In-place split. */ 00233 void split( const CString &Source, const CString &Delimitor, int &begin, int &size, const bool bIgnoreEmpty = true ); 00234 void split( const wstring &Source, const wstring &Delimitor, int &begin, int &size, const bool bIgnoreEmpty = true ); 00235 00236 /* In-place split of partial string. */ 00237 void split( const CString &Source, const CString &Delimitor, int &begin, int &size, int len, const bool bIgnoreEmpty ); /* no default to avoid ambiguity */ 00238 void split( const wstring &Source, const wstring &Delimitor, int &begin, int &size, int len, const bool bIgnoreEmpty ); 00239 00240 // Joins a CStringArray to create a CString according the Deliminator. 00241 CString join( const CString &Delimitor, const CStringArray& Source ); 00242 CString join( const CString &Delimitor, CStringArray::const_iterator begin, CStringArray::const_iterator end ); 00243 00244 CString GetCwd(); 00245 00246 void CRC32( unsigned int &iCRC, const void *pBuffer, size_t iSize ); 00247 unsigned int GetHashForString( const CString &s ); 00248 unsigned int GetHashForFile( const CString &sPath ); 00249 unsigned int GetHashForDirectory( const CString &sDir ); // a hash value that remains the same as long as nothing in the directory has changed 00250 bool DirectoryIsEmpty( const CString &dir ); 00251 00252 bool CompareCStringsAsc(const CString &str1, const CString &str2); 00253 bool CompareCStringsDesc(const CString &str1, const CString &str2); 00254 void SortCStringArray( CStringArray &AddTo, const bool bSortAscending = true ); 00255 00256 /* Find the mean and standard deviation of all numbers in [start,end). */ 00257 float calc_mean(const float *start, const float *end); 00258 float calc_stddev(const float *start, const float *end); 00259 00260 template<class T1, class T2> 00261 int FindIndex( T1 begin, T1 end, const T2 *p ) 00262 { 00263 T1 iter = find( begin, end, p ); 00264 if( iter == end ) 00265 return -1; 00266 return iter - begin; 00267 } 00268 00269 /* Useful for objects with no operator-, eg. map::iterator (more convenient than advance). */ 00270 template<class T> 00271 T Increment( T a ) { ++a; return a; } 00272 template<class T> 00273 T Decrement( T a ) { --a; return a; } 00274 00275 void TrimLeft(CString &str, const char *s = "\r\n\t "); 00276 void TrimRight(CString &str, const char *s = "\r\n\t "); 00277 void StripCrnl(CString &s); 00278 00279 CString DerefRedir(const CString &path); 00280 CString GetRedirContents(const CString &path); 00281 00282 class Regex { 00283 void *reg; 00284 unsigned backrefs; 00285 CString pattern; 00286 void Compile(); 00287 void Release(); 00288 public: 00289 Regex(const CString &pat = ""); 00290 Regex(const Regex &rhs); 00291 Regex &operator=(const Regex &rhs); 00292 ~Regex(); 00293 void Set(const CString &str); 00294 bool Compare(const CString &str); 00295 bool Compare(const CString &str, vector<CString> &matches); 00296 }; 00297 00298 00299 void Replace_Unicode_Markers( CString &Text ); 00300 CString WcharDisplayText(wchar_t c); 00301 00302 CString Basename( const CString &dir ); 00303 CString Dirname( const CString &dir ); 00304 CString Capitalize( const CString &s ); 00305 00306 #ifndef WIN32 00307 #include <unistd.h> /* correct place with correct definitions */ 00308 #endif 00309 00310 /* ASCII-only case insensitivity. */ 00311 struct char_traits_char_nocase: public char_traits<char> 00312 { 00313 static char uptab[256]; 00314 00315 static inline bool eq( char c1, char c2 ) 00316 { return uptab[(unsigned char)c1] == uptab[(unsigned char)c2]; } 00317 00318 static inline bool ne( char c1, char c2 ) 00319 { return uptab[(unsigned char)c1] != uptab[(unsigned char)c2]; } 00320 00321 static inline bool lt( char c1, char c2 ) 00322 { return uptab[(unsigned char)c1] < uptab[(unsigned char)c2]; } 00323 00324 static int compare( const char* s1, const char* s2, size_t n ) 00325 { 00326 int ret = 0; 00327 while( n-- ) 00328 { 00329 ret = fasttoupper(*s1++) - fasttoupper(*s2++); 00330 if( ret != 0 ) 00331 break; 00332 } 00333 return ret; 00334 } 00335 00336 static inline char fasttoupper(char a) 00337 { 00338 return uptab[(unsigned char)a]; 00339 } 00340 00341 static const char *find( const char* s, int n, char a ) 00342 { 00343 a = fasttoupper(a); 00344 while( n-- > 0 && fasttoupper(*s) != a ) 00345 ++s; 00346 00347 if(fasttoupper(*s) == a) 00348 return s; 00349 return NULL; 00350 } 00351 }; 00352 typedef basic_string<char,char_traits_char_nocase> istring; 00353 00354 /* Compatibility/convenience shortcuts. These are actually defined in RageFileManager.h, but 00355 * declared here since they're used in many places. */ 00356 void GetDirListing( const CString &sPath, CStringArray &AddTo, bool bOnlyDirs=false, bool bReturnPathToo=false ); 00357 bool DoesFileExist( const CString &sPath ); 00358 bool IsAFile( const CString &sPath ); 00359 bool IsADirectory( const CString &sPath ); 00360 unsigned GetFileSizeInBytes( const CString &sFilePath ); 00361 void FlushDirCache(); 00362 00363 // call FixSlashes on any path that came from the user 00364 void FixSlashesInPlace( CString &sPath ); 00365 CString FixSlashes( CString sPath ); 00366 void CollapsePath( CString &sPath, bool bRemoveLeadingDot=false ); 00367 00368 bool FromString( const CString &sValue, int &out ); 00369 bool FromString( const CString &sValue, unsigned &out ); 00370 bool FromString( const CString &sValue, float &out ); 00371 bool FromString( const CString &sValue, bool &out ); 00372 00373 CString ToString( int value ); 00374 CString ToString( unsigned value ); 00375 CString ToString( float value ); 00376 CString ToString( bool value ); 00377 00378 00379 // helper file functions used by Bookkeeper and ProfileManager 00380 // 00381 // Helper function for reading/writing scores 00382 // 00383 class RageFile; 00384 bool FileRead(RageFile& f, CString& sOut); 00385 bool FileRead(RageFile& f, int& iOut); 00386 bool FileRead(RageFile& f, unsigned& uOut); 00387 bool FileRead(RageFile& f, float& fOut); 00388 void FileWrite(RageFile& f, const CString& sWrite); 00389 void FileWrite(RageFile& f, int iWrite); 00390 void FileWrite(RageFile& f, size_t uWrite); 00391 void FileWrite(RageFile& f, float fWrite); 00392 00393 bool FileCopy( CString sSrcFile, CString sDstFile ); 00394 00395 #endif 00396 00397 /* 00398 * Copyright (c) 2001-2004 Chris Danford, Glenn Maynard 00399 * All rights reserved. 00400 * 00401 * Permission is hereby granted, free of charge, to any person obtaining a 00402 * copy of this software and associated documentation files (the 00403 * "Software"), to deal in the Software without restriction, including 00404 * without limitation the rights to use, copy, modify, merge, publish, 00405 * distribute, and/or sell copies of the Software, and to permit persons to 00406 * whom the Software is furnished to do so, provided that the above 00407 * copyright notice(s) and this permission notice appear in all copies of 00408 * the Software and that both the above copyright notice(s) and this 00409 * permission notice appear in supporting documentation. 00410 * 00411 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00412 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00413 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF 00414 * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS 00415 * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT 00416 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 00417 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 00418 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00419 * PERFORMANCE OF THIS SOFTWARE. 00420 */

Generated on Thu Jan 27 20:57:30 2005 for StepMania by doxygen 1.3.7