X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Futil.h;h=8dcedb147b4a80ddb05c6f0c098535d572f769ee;hb=882164196e5b1971313493f95a6d027f05e2ec92;hp=4c1e74b7da7ac1fa348f7e328603cdeae5d3ba4e;hpb=e8ef3da7133dd9fc411fa8b3cc8b8fc2f9c58a98;p=novacoin.git diff --git a/src/util.h b/src/util.h index 4c1e74b..8dcedb1 100644 --- a/src/util.h +++ b/src/util.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_UTIL_H @@ -6,7 +7,7 @@ #include "uint256.h" -#ifndef __WXMSW__ +#ifndef WIN32 #include #include #include @@ -23,20 +24,10 @@ #include #include +#include "netbase.h" -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef __int64 int64; -typedef unsigned __int64 uint64; -#else typedef long long int64; typedef unsigned long long uint64; -#endif -#if defined(_MSC_VER) && _MSC_VER < 1300 -#define for if (false) ; else for -#endif -#ifndef _MSC_VER -#define __forceinline inline -#endif #define loop for (;;) #define BEGIN(a) ((char*)&(a)) @@ -52,7 +43,7 @@ typedef unsigned long long uint64; #define snprintf my_snprintf #ifndef PRI64d -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__) +#if defined(_MSC_VER) || defined(__MSVCRT__) #define PRI64d "I64d" #define PRI64u "I64u" #define PRI64x "I64x" @@ -66,14 +57,6 @@ typedef unsigned long long uint64; // This is needed because the foreach macro can't get over the comma in pair #define PAIRTYPE(t1, t2) std::pair -// Used to bypass the rule against non-const reference to temporary -// where it makes sense with wrappers such as CFlatData or CTxDB -template -inline T& REF(const T& val) -{ - return (T&)val; -} - // Align by increasing pointer, must have extra space at end of buffer template T* alignup(T* p) @@ -88,33 +71,16 @@ T* alignup(T* p) return u.ptr; } -#ifdef __WXMSW__ +#ifdef WIN32 #define MSG_NOSIGNAL 0 #define MSG_DONTWAIT 0 -#ifndef UINT64_MAX -#define UINT64_MAX _UI64_MAX -#define INT64_MAX _I64_MAX -#define INT64_MIN _I64_MIN -#endif + #ifndef S_IRUSR #define S_IRUSR 0400 #define S_IWUSR 0200 #endif #define unlink _unlink -typedef int socklen_t; #else -#define WSAGetLastError() errno -#define WSAEINVAL EINVAL -#define WSAEALREADY EALREADY -#define WSAEWOULDBLOCK EWOULDBLOCK -#define WSAEMSGSIZE EMSGSIZE -#define WSAEINTR EINTR -#define WSAEINPROGRESS EINPROGRESS -#define WSAEADDRINUSE EADDRINUSE -#define WSAENOTSOCK EBADF -#define INVALID_SOCKET (SOCKET)(~0) -#define SOCKET_ERROR -1 -typedef u_int SOCKET; #define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d) #define strlwr(psz) to_lower(psz) #define _strlwr(psz) to_lower(psz) @@ -126,20 +92,7 @@ inline void Sleep(int64 n) } #endif -inline int myclosesocket(SOCKET& hSocket) -{ - if (hSocket == INVALID_SOCKET) - return WSAENOTSOCK; -#ifdef __WXMSW__ - int ret = closesocket(hSocket); -#else - int ret = close(hSocket); -#endif - hSocket = INVALID_SOCKET; - return ret; -} -#define closesocket(s) myclosesocket(s) -#if !defined(QT_GUI) && !defined(GUI) +#if !defined(QT_GUI) inline const char* _(const char* psz) { return psz; @@ -185,8 +138,12 @@ bool ParseMoney(const std::string& str, int64& nRet); bool ParseMoney(const char* pszIn, int64& nRet); std::vector ParseHex(const char* psz); std::vector ParseHex(const std::string& str); -void ParseParameters(int argc, char* argv[]); -const char* wxGetTranslation(const char* psz); +bool IsHex(const std::string& str); +std::vector DecodeBase64(const char* p, bool* pfInvalid = NULL); +std::string DecodeBase64(const std::string& str); +std::string EncodeBase64(const unsigned char* pch, size_t len); +std::string EncodeBase64(const std::string& str); +void ParseParameters(int argc, const char*const argv[]); bool WildcardMatch(const char* psz, const char* mask); bool WildcardMatch(const std::string& str, const std::string& mask); int GetFilesize(FILE* file); @@ -195,7 +152,7 @@ std::string GetConfigFile(); std::string GetPidFile(); void CreatePidFile(std::string pidFile, pid_t pid); void ReadConfigFile(std::map& mapSettingsRet, std::map >& mapMultiSettingsRet); -#ifdef __WXMSW__ +#ifdef WIN32 std::string MyGetSpecialFolderPath(int nFolder, bool fCreate); #endif std::string GetDefaultDataDir(); @@ -204,9 +161,11 @@ void ShrinkDebugFile(); int GetRandInt(int nMax); uint64 GetRand(uint64 nMax); int64 GetTime(); +void SetMockTime(int64 nMockTimeIn); int64 GetAdjustedTime(); -void AddTimeData(unsigned int ip, int64 nTime); std::string FormatFullVersion(); +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments); +void AddTimeData(const CNetAddr& ip, int64 nTime); @@ -219,32 +178,17 @@ std::string FormatFullVersion(); - -// Wrapper to automatically initialize critical sections +// Wrapper to automatically initialize mutex class CCriticalSection { -#ifdef __WXMSW__ -protected: - CRITICAL_SECTION cs; -public: - explicit CCriticalSection() { InitializeCriticalSection(&cs); } - ~CCriticalSection() { DeleteCriticalSection(&cs); } - void Enter() { EnterCriticalSection(&cs); } - void Leave() { LeaveCriticalSection(&cs); } - bool TryEnter() { return TryEnterCriticalSection(&cs); } -#else protected: boost::interprocess::interprocess_recursive_mutex mutex; public: explicit CCriticalSection() { } ~CCriticalSection() { } - void Enter() { mutex.lock(); } - void Leave() { mutex.unlock(); } - bool TryEnter() { return mutex.try_lock(); } -#endif -public: - const char* pszFile; - int nLine; + void Enter(const char* pszName, const char* pszFile, int nLine); + void Leave(); + bool TryEnter(const char* pszName, const char* pszFile, int nLine); }; // Automatically leave critical section when leaving block, needed for exception safety @@ -252,37 +196,65 @@ class CCriticalBlock { protected: CCriticalSection* pcs; + public: - CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; pcs->Enter(); } - ~CCriticalBlock() { pcs->Leave(); } + CCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine) + { + pcs = &csIn; + pcs->Enter(pszName, pszFile, nLine); + } + + operator bool() const + { + return true; + } + + ~CCriticalBlock() + { + pcs->Leave(); + } }; -// WARNING: This will catch continue and break! -// break is caught with an assertion, but there's no way to detect continue. -// I'd rather be careful than suffer the other more error prone syntax. -// The compiler will optimise away all this loop junk. #define CRITICAL_BLOCK(cs) \ - for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ - for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) + if (CCriticalBlock criticalblock = CCriticalBlock(cs, #cs, __FILE__, __LINE__)) class CTryCriticalBlock { protected: CCriticalSection* pcs; + public: - CTryCriticalBlock(CCriticalSection& csIn) { pcs = (csIn.TryEnter() ? &csIn : NULL); } - ~CTryCriticalBlock() { if (pcs) pcs->Leave(); } - bool Entered() { return pcs != NULL; } + CTryCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine) + { + pcs = (csIn.TryEnter(pszName, pszFile, nLine) ? &csIn : NULL); + } + + operator bool() const + { + return Entered(); + } + + ~CTryCriticalBlock() + { + if (pcs) + { + pcs->Leave(); + } + } + bool Entered() const { return pcs != NULL; } }; #define TRY_CRITICAL_BLOCK(cs) \ - for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ - for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) + if (CTryCriticalBlock criticalblock = CTryCriticalBlock(cs, #cs, __FILE__, __LINE__)) + +// This is exactly like std::string, but with a custom allocator. +// (secure_allocator<> is defined in serialize.h) +typedef std::basic_string, secure_allocator > SecureString; @@ -388,7 +360,7 @@ inline void PrintHex(const std::vector& vch, const char* pszForma inline int64 GetPerformanceCounter() { int64 nCounter = 0; -#ifdef __WXMSW__ +#ifdef WIN32 QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); #else timeval t; @@ -422,39 +394,57 @@ void skipspaces(T& it) inline bool IsSwitchChar(char c) { -#ifdef __WXMSW__ +#ifdef WIN32 return c == '-' || c == '/'; #else return c == '-'; #endif } -inline std::string GetArg(const std::string& strArg, const std::string& strDefault) -{ - if (mapArgs.count(strArg)) - return mapArgs[strArg]; - return strDefault; -} +/** + * Return string argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (e.g. "1") + * @return command-line argument or default value + */ +std::string GetArg(const std::string& strArg, const std::string& strDefault); -inline int64 GetArg(const std::string& strArg, int64 nDefault) -{ - if (mapArgs.count(strArg)) - return atoi64(mapArgs[strArg]); - return nDefault; -} +/** + * Return integer argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (e.g. 1) + * @return command-line argument (0 if invalid number) or default value + */ +int64 GetArg(const std::string& strArg, int64 nDefault); -inline bool GetBoolArg(const std::string& strArg) -{ - if (mapArgs.count(strArg)) - { - if (mapArgs[strArg].empty()) - return true; - return (atoi(mapArgs[strArg]) != 0); - } - return false; -} +/** + * Return boolean argument or default value + * + * @param strArg Argument to get (e.g. "-foo") + * @param default (true or false) + * @return command-line argument or default value + */ +bool GetBoolArg(const std::string& strArg, bool fDefault=false); +/** + * Set an argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param strValue Value (e.g. "1") + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetArg(const std::string& strArg, const std::string& strValue); +/** + * Set a boolean argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param fValue Value (e.g. false) + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetBoolArg(const std::string& strArg, bool fValue); @@ -463,14 +453,6 @@ inline bool GetBoolArg(const std::string& strArg) -inline void heapchk() -{ -#ifdef __WXMSW__ - /// for debugging - //if (_heapchk() != _HEAPOK) - // DebugBreak(); -#endif -} // Randomize the stack to help protect against buffer overrun exploits #define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \ @@ -547,7 +529,7 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end, } template -uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION) +uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) { // Most of the time is spent allocating and deallocating CDataStream's // buffer. If this ever needs to be optimized further, make a CStaticStream @@ -568,6 +550,61 @@ inline uint160 Hash160(const std::vector& vch) } +// Median filter over a stream of values +// Returns the median of the last N numbers +template class CMedianFilter +{ +private: + std::vector vValues; + std::vector vSorted; + int nSize; +public: + CMedianFilter(int size, T initial_value): + nSize(size) + { + vValues.reserve(size); + vValues.push_back(initial_value); + vSorted = vValues; + } + + void input(T value) + { + if(vValues.size() == nSize) + { + vValues.erase(vValues.begin()); + } + vValues.push_back(value); + + vSorted.resize(vValues.size()); + std::copy(vValues.begin(), vValues.end(), vSorted.begin()); + std::sort(vSorted.begin(), vSorted.end()); + } + + T median() const + { + int size = vSorted.size(); + assert(size>0); + if(size & 1) // Odd number of elements + { + return vSorted[size/2]; + } + else // Even number of elements + { + return (vSorted[size/2-1] + vSorted[size/2]) / 2; + } + } + + int size() const + { + return vValues.size(); + } + + std::vector sorted () const + { + return vSorted; + } +}; + @@ -579,7 +616,7 @@ inline uint160 Hash160(const std::vector& vch) // Note: It turns out we might have been able to use boost::thread // by using TerminateThread(boost::thread.native_handle(), 0); -#ifdef __WXMSW__ +#ifdef WIN32 typedef HANDLE pthread_t; inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) @@ -621,7 +658,10 @@ inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=fa return (pthread_t)0; } if (!fWantHandle) + { + pthread_detach(hthread); return (pthread_t)-1; + } return hthread; } @@ -646,7 +686,7 @@ inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode) return (pthread_cancel(hthread) == 0); } -inline void ExitThread(unsigned int nExitCode) +inline void ExitThread(size_t nExitCode) { pthread_exit((void*)nExitCode); } @@ -658,10 +698,10 @@ inline void ExitThread(unsigned int nExitCode) inline bool AffinityBugWorkaround(void(*pfn)(void*)) { -#ifdef __WXMSW__ +#ifdef WIN32 // Sometimes after a few hours affinity gets stuck on one processor - DWORD dwProcessAffinityMask = -1; - DWORD dwSystemAffinityMask = -1; + DWORD_PTR dwProcessAffinityMask = -1; + DWORD_PTR dwSystemAffinityMask = -1; GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask); DWORD dwPrev1 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask); DWORD dwPrev2 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask); @@ -676,4 +716,11 @@ inline bool AffinityBugWorkaround(void(*pfn)(void*)) return false; } +inline uint32_t ByteReverse(uint32_t value) +{ + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return (value<<16) | (value>>16); +} + #endif +