better wallet.dat flush, consolidated QueryPerformanceCounter, PRI64d printf portability
[novacoin.git] / util.h
1 // Copyright (c) 2009 Satoshi Nakamoto\r
2 // Distributed under the MIT/X11 software license, see the accompanying\r
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.\r
4 \r
5 \r
6 #if defined(_MSC_VER) || defined(__BORLANDC__)\r
7 typedef __int64  int64;\r
8 typedef unsigned __int64  uint64;\r
9 #else\r
10 typedef long long  int64;\r
11 typedef unsigned long long  uint64;\r
12 #endif\r
13 #if defined(_MSC_VER) && _MSC_VER < 1300\r
14 #define for  if (false) ; else for\r
15 #endif\r
16 #ifndef _MSC_VER\r
17 #define __forceinline  inline\r
18 #endif\r
19 \r
20 #define foreach             BOOST_FOREACH\r
21 #define loop                for (;;)\r
22 #define BEGIN(a)            ((char*)&(a))\r
23 #define END(a)              ((char*)&((&(a))[1]))\r
24 #define UBEGIN(a)           ((unsigned char*)&(a))\r
25 #define UEND(a)             ((unsigned char*)&((&(a))[1]))\r
26 #define ARRAYLEN(array)     (sizeof(array)/sizeof((array)[0]))\r
27 #define printf              OutputDebugStringF\r
28 \r
29 #ifdef snprintf\r
30 #undef snprintf\r
31 #endif\r
32 #define snprintf my_snprintf\r
33 \r
34 #ifndef PRI64d\r
35 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)\r
36 #define PRI64d  "I64d"\r
37 #define PRI64u  "I64u"\r
38 #define PRI64x  "I64x"\r
39 #else\r
40 #define PRI64d  "lld"\r
41 #define PRI64u  "llu"\r
42 #define PRI64x  "llx"\r
43 #endif\r
44 #endif\r
45 \r
46 // This is needed because the foreach macro can't get over the comma in pair<t1, t2>\r
47 #define PAIRTYPE(t1, t2)    pair<t1, t2>\r
48 \r
49 // Used to bypass the rule against non-const reference to temporary\r
50 // where it makes sense with wrappers such as CFlatData or CTxDB\r
51 template<typename T>\r
52 inline T& REF(const T& val)\r
53 {\r
54     return (T&)val;\r
55 }\r
56 \r
57 \r
58 \r
59 \r
60 \r
61 \r
62 \r
63 extern bool fDebug;\r
64 extern bool fPrintToDebugger;\r
65 extern bool fPrintToConsole;\r
66 extern map<string, string> mapArgs;\r
67 \r
68 void RandAddSeed();\r
69 void RandAddSeedPerfmon();\r
70 int my_snprintf(char* buffer, size_t limit, const char* format, ...);\r
71 string strprintf(const char* format, ...);\r
72 bool error(const char* format, ...);\r
73 void PrintException(std::exception* pex, const char* pszThread);\r
74 void LogException(std::exception* pex, const char* pszThread);\r
75 void ParseString(const string& str, char c, vector<string>& v);\r
76 string FormatMoney(int64 n, bool fPlus=false);\r
77 bool ParseMoney(const char* pszIn, int64& nRet);\r
78 vector<unsigned char> ParseHex(const char* psz);\r
79 vector<unsigned char> ParseHex(const std::string& str);\r
80 bool FileExists(const char* psz);\r
81 int GetFilesize(FILE* file);\r
82 uint64 GetRand(uint64 nMax);\r
83 int64 GetTime();\r
84 int64 GetAdjustedTime();\r
85 void AddTimeData(unsigned int ip, int64 nTime);\r
86 \r
87 \r
88 \r
89 \r
90 \r
91 \r
92 \r
93 \r
94 \r
95 \r
96 \r
97 \r
98 // Wrapper to automatically initialize critical sections\r
99 class CCriticalSection\r
100 {\r
101 #ifdef __WXMSW__\r
102 protected:\r
103     CRITICAL_SECTION cs;\r
104 public:\r
105     explicit CCriticalSection() { InitializeCriticalSection(&cs); }\r
106     ~CCriticalSection() { DeleteCriticalSection(&cs); }\r
107     void Enter() { EnterCriticalSection(&cs); }\r
108     void Leave() { LeaveCriticalSection(&cs); }\r
109     bool TryEnter() { return TryEnterCriticalSection(&cs); }\r
110 #else\r
111 protected:\r
112     wxMutex mutex;\r
113 public:\r
114     explicit CCriticalSection() { }\r
115     ~CCriticalSection() { }\r
116     void Enter() { mutex.Lock(); }\r
117     void Leave() { mutex.Unlock(); }\r
118     bool TryEnter() { return mutex.TryLock() == wxMUTEX_NO_ERROR; }\r
119 #endif\r
120 public:\r
121     char* pszFile;\r
122     int nLine;\r
123 };\r
124 \r
125 // Automatically leave critical section when leaving block, needed for exception safety\r
126 class CCriticalBlock\r
127 {\r
128 protected:\r
129     CCriticalSection* pcs;\r
130 public:\r
131     CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; pcs->Enter(); }\r
132     ~CCriticalBlock() { pcs->Leave(); }\r
133 };\r
134 \r
135 // WARNING: This will catch continue and break!\r
136 // break is caught with an assertion, but there's no way to detect continue.\r
137 // I'd rather be careful than suffer the other more error prone syntax.\r
138 // The compiler will optimise away all this loop junk.\r
139 #define CRITICAL_BLOCK(cs)     \\r
140     for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false)  \\r
141     for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)\r
142 \r
143 class CTryCriticalBlock\r
144 {\r
145 protected:\r
146     CCriticalSection* pcs;\r
147 public:\r
148     CTryCriticalBlock(CCriticalSection& csIn) { pcs = (csIn.TryEnter() ? &csIn : NULL); }\r
149     ~CTryCriticalBlock() { if (pcs) pcs->Leave(); }\r
150     bool Entered() { return pcs != NULL; }\r
151 };\r
152 \r
153 #define TRY_CRITICAL_BLOCK(cs)     \\r
154     for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false)  \\r
155     for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)\r
156 \r
157 \r
158 \r
159 \r
160 \r
161 \r
162 \r
163 \r
164 \r
165 \r
166 \r
167 \r
168 inline int OutputDebugStringF(const char* pszFormat, ...)\r
169 {\r
170     int ret = 0;\r
171 #ifdef __WXDEBUG__\r
172     if (!fPrintToConsole)\r
173     {\r
174         // print to debug.log\r
175         FILE* fileout = fopen("debug.log", "a");\r
176         if (fileout)\r
177         {\r
178             va_list arg_ptr;\r
179             va_start(arg_ptr, pszFormat);\r
180             ret = vfprintf(fileout, pszFormat, arg_ptr);\r
181             va_end(arg_ptr);\r
182             fclose(fileout);\r
183         }\r
184     }\r
185 \r
186 #ifdef __WXMSW__\r
187     if (fPrintToDebugger)\r
188     {\r
189         // accumulate a line at a time\r
190         static CCriticalSection cs_OutputDebugStringF;\r
191         CRITICAL_BLOCK(cs_OutputDebugStringF)\r
192         {\r
193             static char pszBuffer[50000];\r
194             static char* pend;\r
195             if (pend == NULL)\r
196                 pend = pszBuffer;\r
197             va_list arg_ptr;\r
198             va_start(arg_ptr, pszFormat);\r
199             int limit = END(pszBuffer) - pend - 2;\r
200             int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);\r
201             va_end(arg_ptr);\r
202             if (ret < 0 || ret >= limit)\r
203             {\r
204                 pend = END(pszBuffer) - 2;\r
205                 *pend++ = '\n';\r
206             }\r
207             else\r
208                 pend += ret;\r
209             *pend = '\0';\r
210             char* p1 = pszBuffer;\r
211             char* p2;\r
212             while (p2 = strchr(p1, '\n'))\r
213             {\r
214                 p2++;\r
215                 char c = *p2;\r
216                 *p2 = '\0';\r
217                 OutputDebugString(p1);\r
218                 *p2 = c;\r
219                 p1 = p2;\r
220             }\r
221             if (p1 != pszBuffer)\r
222                 memmove(pszBuffer, p1, pend - p1 + 1);\r
223             pend -= (p1 - pszBuffer);\r
224         }\r
225     }\r
226 #endif\r
227 #endif\r
228 \r
229     if (fPrintToConsole)\r
230     {\r
231         // print to console\r
232         va_list arg_ptr;\r
233         va_start(arg_ptr, pszFormat);\r
234         ret = vprintf(pszFormat, arg_ptr);\r
235         va_end(arg_ptr);\r
236     }\r
237     return ret;\r
238 }\r
239 \r
240 \r
241 \r
242 \r
243 \r
244 \r
245 \r
246 \r
247 \r
248 \r
249 inline string i64tostr(int64 n)\r
250 {\r
251     return strprintf("%"PRI64d, n);\r
252 }\r
253 \r
254 inline string itostr(int n)\r
255 {\r
256     return strprintf("%d", n);\r
257 }\r
258 \r
259 inline int64 atoi64(const char* psz)\r
260 {\r
261 #ifdef _MSC_VER\r
262     return _atoi64(psz);\r
263 #else\r
264     return strtoll(psz, NULL, 10);\r
265 #endif\r
266 }\r
267 \r
268 inline int64 atoi64(const string& str)\r
269 {\r
270 #ifdef _MSC_VER\r
271     return _atoi64(str.c_str());\r
272 #else\r
273     return strtoll(str.c_str(), NULL, 10);\r
274 #endif\r
275 }\r
276 \r
277 inline int atoi(const string& str)\r
278 {\r
279     return atoi(str.c_str());\r
280 }\r
281 \r
282 inline int roundint(double d)\r
283 {\r
284     return (int)(d > 0 ? d + 0.5 : d - 0.5);\r
285 }\r
286 \r
287 template<typename T>\r
288 string HexStr(const T itbegin, const T itend, bool fSpaces=true)\r
289 {\r
290     const unsigned char* pbegin = (const unsigned char*)&itbegin[0];\r
291     const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);\r
292     string str;\r
293     for (const unsigned char* p = pbegin; p != pend; p++)\r
294         str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);\r
295     return str;\r
296 }\r
297 \r
298 inline string HexStr(vector<unsigned char> vch, bool fSpaces=true)\r
299 {\r
300     return HexStr(vch.begin(), vch.end(), fSpaces);\r
301 }\r
302 \r
303 template<typename T>\r
304 string HexNumStr(const T itbegin, const T itend, bool f0x=true)\r
305 {\r
306     const unsigned char* pbegin = (const unsigned char*)&itbegin[0];\r
307     const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);\r
308     string str = (f0x ? "0x" : "");\r
309     for (const unsigned char* p = pend-1; p >= pbegin; p--)\r
310         str += strprintf("%02X", *p);\r
311     return str;\r
312 }\r
313 \r
314 template<typename T>\r
315 void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)\r
316 {\r
317     printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());\r
318 }\r
319 \r
320 inline void PrintHex(vector<unsigned char> vch, const char* pszFormat="%s", bool fSpaces=true)\r
321 {\r
322     printf(pszFormat, HexStr(vch, fSpaces).c_str());\r
323 }\r
324 \r
325 inline int64 PerformanceCounter()\r
326 {\r
327     int64 nCounter = 0;\r
328     QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);\r
329     return nCounter;\r
330 }\r
331 \r
332 #ifndef __WXMSW__\r
333 inline void Sleep(unsigned int nMilliseconds)\r
334 {\r
335     wxMilliSleep(nMilliseconds);\r
336 }\r
337 #endif\r
338 \r
339 \r
340 \r
341 \r
342 \r
343 \r
344 \r
345 \r
346 \r
347 inline void heapchk()\r
348 {\r
349     if (_heapchk() != _HEAPOK)\r
350         DebugBreak();\r
351 }\r
352 \r
353 // Randomize the stack to help protect against buffer overrun exploits\r
354 #define IMPLEMENT_RANDOMIZE_STACK(ThreadFn)                         \\r
355     {                                                               \\r
356         static char nLoops;                                         \\r
357         if (nLoops <= 0)                                            \\r
358             nLoops = GetRand(50) + 1;                               \\r
359         if (nLoops-- > 1)                                           \\r
360         {                                                           \\r
361             ThreadFn;                                               \\r
362             return;                                                 \\r
363         }                                                           \\r
364     }\r
365 \r
366 #define CATCH_PRINT_EXCEPTION(pszFn)     \\r
367     catch (std::exception& e) {          \\r
368         PrintException(&e, (pszFn));     \\r
369     } catch (...) {                      \\r
370         PrintException(NULL, (pszFn));   \\r
371     }\r
372 \r
373 \r
374 \r
375 \r
376 \r
377 \r
378 \r
379 \r
380 \r
381 \r
382 template<typename T1>\r
383 inline uint256 Hash(const T1 pbegin, const T1 pend)\r
384 {\r
385     uint256 hash1;\r
386     SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);\r
387     uint256 hash2;\r
388     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);\r
389     return hash2;\r
390 }\r
391 \r
392 template<typename T1, typename T2>\r
393 inline uint256 Hash(const T1 p1begin, const T1 p1end,\r
394                     const T2 p2begin, const T2 p2end)\r
395 {\r
396     uint256 hash1;\r
397     SHA256_CTX ctx;\r
398     SHA256_Init(&ctx);\r
399     SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));\r
400     SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));\r
401     SHA256_Final((unsigned char*)&hash1, &ctx);\r
402     uint256 hash2;\r
403     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);\r
404     return hash2;\r
405 }\r
406 \r
407 template<typename T1, typename T2, typename T3>\r
408 inline uint256 Hash(const T1 p1begin, const T1 p1end,\r
409                     const T2 p2begin, const T2 p2end,\r
410                     const T3 p3begin, const T3 p3end)\r
411 {\r
412     uint256 hash1;\r
413     SHA256_CTX ctx;\r
414     SHA256_Init(&ctx);\r
415     SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));\r
416     SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));\r
417     SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]));\r
418     SHA256_Final((unsigned char*)&hash1, &ctx);\r
419     uint256 hash2;\r
420     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);\r
421     return hash2;\r
422 }\r
423 \r
424 template<typename T>\r
425 uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)\r
426 {\r
427     // Most of the time is spent allocating and deallocating CDataStream's\r
428     // buffer.  If this ever needs to be optimized further, make a CStaticStream\r
429     // class with its buffer on the stack.\r
430     CDataStream ss(nType, nVersion);\r
431     ss.reserve(10000);\r
432     ss << obj;\r
433     return Hash(ss.begin(), ss.end());\r
434 }\r
435 \r
436 inline uint160 Hash160(const vector<unsigned char>& vch)\r
437 {\r
438     uint256 hash1;\r
439     SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);\r
440     uint160 hash2;\r
441     RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);\r
442     return hash2;\r
443 }\r